Changes in / [e135751:51b46f2] in mainline
- Files:
-
- 1 added
- 10 deleted
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
re135751 r51b46f2 42 42 CONFIG_HEADER = config.h 43 43 44 .PHONY: all precheck cscope autotool config_auto config_default config distclean clean check distfile dist44 .PHONY: all precheck cscope autotool config_auto config_default config distclean clean check 45 45 46 46 all: $(COMMON_MAKEFILE) $(COMMON_HEADER) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) … … 64 64 endif 65 65 66 # Autotool (detects compiler features)67 68 66 $(COMMON_MAKEFILE): autotool 69 67 $(COMMON_HEADER): autotool … … 72 70 $(AUTOTOOL) 73 71 -[ -f $(COMMON_HEADER_PREV) ] && diff -q $(COMMON_HEADER_PREV) $(COMMON_HEADER) && mv -f $(COMMON_HEADER_PREV) $(COMMON_HEADER) 74 75 # Build-time configuration76 72 77 73 $(CONFIG_MAKEFILE): config_default … … 88 84 $(CONFIG) $< 89 85 90 # Distribution files91 92 distfile: all93 $(MAKE) -C dist distfile94 95 dist:96 $(MAKE) -C dist dist97 98 # Cleaning99 100 86 distclean: clean 101 rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc dist/HelenOS-*87 rm -f $(CSCOPE).out $(COMMON_MAKEFILE) $(COMMON_HEADER) $(COMMON_HEADER_PREV) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) tools/*.pyc tools/checkers/*.pyc 102 88 103 89 clean: -
boot/arch/sparc64/include/arch.h
re135751 r51b46f2 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)44 43 45 44 #define NWINDOWS 8 -
boot/arch/sparc64/src/asm.S
re135751 r51b46f2 152 152 .global ofw 153 153 ofw: 154 save %sp, - (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp154 save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp 155 155 set ofw_cif, %l0 156 156 ldx [%l0], %l0 -
boot/arch/sparc64/src/main.c
re135751 r51b46f2 190 190 bootinfo.memmap.zones[0].start += OBP_BIAS; 191 191 bootinfo.memmap.zones[0].size -= OBP_BIAS; 192 bootinfo.memmap.total -= OBP_BIAS;193 192 } 194 193 … … 205 204 bootinfo.physmem_start = ofw_get_physmem_start(); 206 205 ofw_memmap(&bootinfo.memmap); 207 208 if (arch == ARCH_SUN4V)209 sun4v_fixups();210 206 211 207 void *bootinfo_pa = ofw_translate(&bootinfo); … … 257 253 258 254 /* 259 * At this point, we claim and map the physical memory that we260 * aregoing to use. We should be safe in case of the virtual255 * At this point, we claim the physical memory that we are 256 * going to use. We should be safe in case of the virtual 261 257 * address space because the OpenFirmware, according to its 262 * SPARC binding, should restrict its use of virtual memory to 263 * addresses from [0xffd00000; 0xffefffff] and [0xfe000000; 264 * 0xfeffffff]. 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 * 265 269 */ 266 270 ofw_claim_phys(bootinfo.physmem_start + dest[i - 1], 267 271 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);271 272 272 273 int err = inflate(components[i - 1].start, components[i - 1].size, … … 303 304 sun4u_smp(); 304 305 306 if (arch == ARCH_SUN4V) 307 sun4v_fixups(); 308 305 309 printf("Booting the kernel ...\n"); 306 310 jump_to_kernel(bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo, subarch, -
boot/generic/src/balloc.c
re135751 r51b46f2 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
re135751 r51b46f2 41 41 .global switch_to_userspace 42 42 switch_to_userspace: 43 save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp 43 wrpr PSTATE_PRIV_BIT, %pstate 44 save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp 44 45 flushw 45 46 wrpr %g0, 0, %cleanwin ! avoid information leak -
tools/toolchain.sh
re135751 r51b46f2 28 28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 29 # 30 31 GMP_MAIN=<<EOF32 #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 me40 #endif41 EOF42 43 MPFR_MAIN=<<EOF44 #if MPFR_VERSION < MPFR_VERSION_NUM(2, 4, 2)45 choke me46 #endif47 EOF48 49 MPC_MAIN=<<EOF50 #if MPC_VERSION < MPC_VERSION_NUM(0, 8, 1)51 choke me52 #endif53 EOF54 55 #56 # Check if the library described in the argument57 # 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" ] ; then78 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 echo83 echo " ===== Compiler output ====="84 cat "${FNAME}.log"85 echo " ==========================="86 echo87 else88 echo " ${DEPENDENCY} found"89 rm -f "${FNAME}.log" "${FNAME}.o" "${FNAME}.c"90 fi91 }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 echo99 }100 30 101 31 check_error() { … … 139 69 echo " sparc64 SPARC V9" 140 70 echo " all build all targets" 141 echo142 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."145 71 echo 146 72 … … 192 118 echo " - native C library with headers" 193 119 echo 120 121 show_countdown 10 194 122 } 195 123 … … 353 281 354 282 show_dependencies 355 check_dependecies356 show_countdown 10357 283 358 284 case "$1" in -
uspace/app/bdsh/cmds/modules/mount/mount.c
re135751 r51b46f2 31 31 #include <vfs/vfs.h> 32 32 #include <errno.h> 33 #include <getopt.h>34 33 #include "config.h" 35 34 #include "util.h" … … 41 40 static const char *cmdname = "mount"; 42 41 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 */ 42 /* Dispays help for mount in various levels */ 50 43 void help_cmd_mount(unsigned int level) 51 44 { … … 66 59 unsigned int argc; 67 60 const char *mopts = ""; 68 int rc , c, opt_ind;61 int rc; 69 62 70 63 argc = cli_count_args(argv); 71 64 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 81 65 if ((argc < 4) || (argc > 5)) { 82 printf("%s: invalid number of arguments. Try `mount --help'\n",66 printf("%s: invalid number of arguments.\n", 83 67 cmdname); 84 68 return CMD_FAILURE; -
uspace/drv/pciintel/pci.c
re135751 r51b46f2 59 59 #include <ddi.h> 60 60 #include <libarch/ddi.h> 61 #include <pci_dev_iface.h>62 61 63 62 #include "pci.h" … … 122 121 } 123 122 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 133 123 static hw_res_ops_t pciintel_hw_res_ops = { 134 124 &pciintel_get_resources, … … 136 126 }; 137 127 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 }; 128 static ddf_dev_ops_t pci_fun_ops; 151 129 152 130 static int pci_add_device(ddf_dev_t *); … … 615 593 { 616 594 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 617 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;618 595 } 619 596 -
uspace/drv/uhci-hcd/main.c
re135751 r51b46f2 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 40 36 #include <usb_iface.h> 41 37 #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 52 53 /*----------------------------------------------------------------------------*/ 53 54 static driver_ops_t uhci_driver_ops = { … … 69 70 } 70 71 /*----------------------------------------------------------------------------*/ 72 #define CHECK_RET_RETURN(ret, message...) \ 73 if (ret != EOK) { \ 74 usb_log_error(message); \ 75 return ret; \ 76 } 77 71 78 static int uhci_add_device(ddf_dev_t *device) 72 79 { 73 80 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 }82 81 83 82 usb_log_info("uhci_add_device() called\n"); … … 89 88 int ret = 90 89 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 91 CHECK_RET_FREE_HC_RETURN(ret, 90 91 CHECK_RET_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_disable_legacy(device); 97 CHECK_RET_FREE_HC_RETURN(ret, 98 "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret)); 96 // ret = pci_enable_interrupts(device); 97 // CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret); 99 98 100 #if 0 101 ret = pci_enable_interrupts(device); 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"); 102 103 ret = uhci_init(uhci_hc, device, (void*)io_reg_base, io_reg_size); 102 104 if (ret != EOK) { 103 usb_log_ warning(104 "Failed(%d) to enable interrupts, fall back to polling.\n",105 ret);105 usb_log_error("Failed to init uhci-hcd.\n"); 106 free(uhci_hc); 107 return ret; 106 108 } 107 #endif108 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_RETURN118 109 119 110 /* 120 * We might free hcd, but that does not matter since no one111 * We might free uhci_hc, but that does not matter since no one 121 112 * else would access driver_data anyway. 122 113 */ 123 device->driver_data = hcd; 114 device->driver_data = uhci_hc; 115 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 } 124 123 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 */ 139 ret = register_interrupt_handler(device, irq, irq_handler, 140 &hcd->interrupt_code); 141 CHECK_RET_FINI_FREE_RETURN(ret, 142 "Failed(%d) to register interrupt handler.\n", ret); 143 124 ddf_fun_t *rh; 144 125 ret = setup_root_hub(&rh, device); 145 CHECK_RET_FINI_FREE_RETURN(ret, 146 "Failed(%d) to setup UHCI root hub.\n", ret); 147 rh->driver_data = hcd->ddf_instance; 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; 148 133 149 134 ret = ddf_fun_bind(rh); 150 CHECK_RET_FINI_FREE_RETURN(ret, 151 "Failed(%d) to register UHCI root hub.\n", ret); 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 } 152 142 153 143 return EOK; 154 #undef CHECK_RET_FINI_FREE_RETURN155 144 } 156 145 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/pci.c
re135751 r51b46f2 40 40 41 41 #include <usb/debug.h> 42 #include <pci_dev_iface.h>43 42 44 43 #include "pci.h" … … 129 128 return enabled ? EOK : EIO; 130 129 } 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 /*----------------------------------------------------------------------------*/153 130 /** 154 131 * @} -
uspace/drv/uhci-hcd/pci.h
re135751 r51b46f2 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 *);43 42 44 43 #endif -
uspace/drv/uhci-hcd/uhci.c
re135751 r51b46f2 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 /* Create UHCI function. */ 117 /* 118 * Create UHCI function. 119 */ 118 120 instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci"); 119 121 ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK; 120 CHECK_RET_DEST_FUN_RETURN(ret, 121 "Failed to create UHCI device function.\n"); 122 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to create UHCI device function.\n"); 122 123 123 124 instance->ddf_instance->ops = &uhci_ops; … … 125 126 126 127 ret = ddf_fun_bind(instance->ddf_instance); 127 CHECK_RET_DEST_FUN_RETURN(ret, 128 "Failed(%d) to bind UHCI device function: %s.\n", 128 CHECK_RET_DEST_FUN_RETURN(ret, "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, 135 "Failed(%d) to gain access to registers at %p: %s.\n", 134 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to gain access to registers at %p: %s.\n", 136 135 ret, str_error(ret), io); 137 136 instance->registers = io; 138 usb_log_debug("Device registers at %p(%u) accessible.\n", 139 io, reg_size); 137 usb_log_debug("Device registers at %p(%u) accessible.\n", io, reg_size); 140 138 141 139 ret = uhci_init_mem_structures(instance); 142 CHECK_RET_DEST_FUN_RETURN(ret, 143 "Failed to initialize UHCI memory structures.\n"); 140 CHECK_RET_DEST_FUN_RETURN(ret, "Failed to initialize UHCI memory structures.\n"); 144 141 145 142 uhci_init_hw(instance); 146 instance->cleaner = 147 143 144 instance->cleaner = fibril_create(uhci_interrupt_emulator, instance); 148 145 fibril_add_ready(instance->cleaner); 149 146 … … 158 155 void uhci_init_hw(uhci_t *instance) 159 156 { 160 assert(instance);161 162 157 /* reset everything, who knows what touched it before us */ 163 158 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET); … … 176 171 /* enable all interrupts, but resume interrupt */ 177 172 pio_write_16(&instance->registers->usbintr, 178 173 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 179 174 180 175 /* Start the hc with large(64B) packet FSBR */ … … 205 200 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 206 201 instance->interrupt_code.cmdcount = 207 202 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 208 203 } 209 204 … … 254 249 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 255 250 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 256 257 251 ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL"); 258 252 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 259 260 253 ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW"); 261 254 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 262 263 255 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 264 256 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list."); … … 300 292 low_speed, batch->transfer_type, batch->max_packet_size)) { 301 293 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 302 294 low_speed ? "LOW" : "FULL" , batch->transfer_type, 303 295 batch->max_packet_size); 304 296 return ENOTSUP; … … 317 309 { 318 310 assert(instance); 311 // if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0) 312 // return; 313 // usb_log_debug2("UHCI interrupt: %X.\n", status); 319 314 transfer_list_remove_finished(&instance->transfers_interrupt); 320 315 transfer_list_remove_finished(&instance->transfers_control_slow); … … 345 340 uhci_t *instance = (uhci_t*)arg; 346 341 assert(instance); 347 348 #define QH(queue) \349 instance->transfers_##queue.queue_head350 351 342 while (1) { 352 343 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 353 344 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 354 const uint16_t intr = 355 pio_read_16(&instance->registers->usbintr); 356 345 const uint16_t intr = pio_read_16(&instance->registers->usbintr); 357 346 if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) { 358 347 usb_log_debug2("Command: %X Status: %X Intr: %x\n", … … 364 353 if (frame_list != addr_to_phys(instance->frame_list)) { 365 354 usb_log_debug("Framelist address: %p vs. %p.\n", 366 frame_list, addr_to_phys(instance->frame_list)); 367 } 368 355 frame_list, addr_to_phys(instance->frame_list)); 356 } 369 357 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 370 358 usb_log_debug2("Framelist item: %d \n", frnum ); 371 359 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) {360 queue_head_t* qh = instance->transfers_interrupt.queue_head; 361 362 if ((instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) { 375 363 usb_log_debug("Interrupt QH: %p vs. %p.\n", 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 } 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 */ 399 391 async_usleep(UHCI_DEBUGER_TIMEOUT); 400 392 } 401 393 return 0; 402 #undef QH403 394 } 404 395 /*----------------------------------------------------------------------------*/ 405 396 bool allowed_usb_packet( 406 397 bool low_speed, usb_transfer_type_t transfer, size_t size) 407 398 { 408 399 /* see USB specification chapter 5.5-5.8 for magic numbers used here */ 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); 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); 419 409 } 420 410 return false; -
uspace/drv/usbhid/Makefile
re135751 r51b46f2 40 40 main.c \ 41 41 conv.c \ 42 hidreq.c \43 kbddev.c \44 hiddev.c \45 42 $(STOLEN_LAYOUT_SOURCES) 46 43 -
uspace/drv/usbhid/conv.c
re135751 r51b46f2 163 163 }; 164 164 165 unsigned int usb hid_parse_scancode(int scancode)165 unsigned int usbkbd_parse_scancode(int scancode) 166 166 { 167 // console_ev_type_t type; 167 168 unsigned int key; 168 169 int *map = scanmap_simple; 169 170 size_t map_length = sizeof(scanmap_simple) / sizeof(int); 170 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 171 207 if ((scancode < 0) || ((size_t) scancode >= map_length)) 172 208 return -1; … … 174 210 key = map[scancode]; 175 211 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); 176 226 return key; 177 227 } -
uspace/drv/usbhid/conv.h
re135751 r51b46f2 37 37 #define USBHID_CONV_H_ 38 38 39 unsigned int usb hid_parse_scancode(int scancode);39 unsigned int usbkbd_parse_scancode(int scancode); 40 40 41 #endif /* USBHID_CONV_H_ */41 #endif 42 42 43 43 /** -
uspace/drv/usbhid/descdump.h
re135751 r51b46f2 37 37 #define USBHID_DESCDUMP_H_ 38 38 39 #include <usb/descriptor.h> 40 #include <usb/classes/hid.h> 39 #include "hid.h" 41 40 42 41 void dump_standard_configuration_descriptor( -
uspace/drv/usbhid/main.c
re135751 r51b46f2 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> 43 #include <errno.h> 44 #include <str_error.h> 45 #include <fibril.h> 39 46 #include <usb/debug.h> 40 #include <errno.h> 41 42 #include "kbddev.h" 43 44 /*----------------------------------------------------------------------------*/ 45 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 59 #define BUFFER_SIZE 8 60 #define BUFFER_OUT_SIZE 1 46 61 #define NAME "usbhid" 47 62 48 /*----------------------------------------------------------------------------*/ 49 50 static int usbhid_add_device(ddf_dev_t *dev) 51 { 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"); 63 //#define GUESSED_POLL_ENDPOINT 1 64 #define BOOTP_REPORT_SIZE 6 65 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) 93 { 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; 107 } 108 109 async_answer_0(icallid, EINVAL); 110 } 111 112 #if 0 113 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 #endif 118 119 /* 120 * TODO: Move somewhere else 121 */ 122 /* 123 #define BYTES_PER_LINE 12 124 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.c 141 */ 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 3 156 157 static layout_op_t *layout[NUM_LAYOUTS] = { 158 &us_qwerty_op, 159 &us_dvorak_op, 160 &cz_op 161 }; 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 KANA 253 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 else 296 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 released 315 * to pressed. This prevents autorepeat from messing 316 * 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-paste 368 */ 369 370 /* 371 * TODO: 372 * 1) key press / key release - how does the keyboard notify about 373 * release? 374 * 2) layouts (use the already defined), not important now 375 * 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_LOCK 394 * 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 in 398 * that way 399 */ 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 pressed 406 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 released 413 if (usb_hid_modifiers_keycodes[i] != 0) { 414 kbd_push_ev(KEY_RELEASE, 415 usb_hid_modifiers_keycodes[i], kbd_dev); 416 } 417 } // no change 418 } 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 implementation 432 433 // key releases 434 for (j = 0; j < kbd_dev->keycode_count; ++j) { 435 // try to find the old key in the new key list 436 i = 0; 437 while (i < kbd_dev->keycode_count 438 && 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 released 444 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 happens 449 } 450 } 451 452 // key presses 453 for (i = 0; i < kbd_dev->keycode_count; ++i) { 454 // try to find the new key in the old key list 455 j = 0; 456 while (j < kbd_dev->keycode_count 457 && 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 pressed 463 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 happens 469 } 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 parser 482 */ 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 functions 513 */ 514 //static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev) 515 //{ 516 // // iterate over all configurations and interfaces 517 // // TODO: more configurations!! 518 // unsigned i; 519 // for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) { 520 // // TODO: endianness 521 // 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 descriptor 526 // kbd_dev->conf->interfaces[i].report_desc = 527 // (uint8_t *)malloc(length); 528 529 // // get the descriptor from the device 530 // 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_nesting 559 }; 560 561 usb_dp_parser_data_t parser_data = { 562 .data = config_desc, 563 .size = config_desc_size, 564 .arg = NULL 565 }; 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 632 return EOK; 633 } 634 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); 59 694 return EREFUSED; 60 695 } 61 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 62 725 return EOK; 63 726 } 64 727 65 /*----------------------------------------------------------------------------*/ 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 } 66 938 67 939 static driver_ops_t kbd_driver_ops = { 68 .add_device = usb hid_add_device,940 .add_device = usbkbd_add_device, 69 941 }; 70 71 /*----------------------------------------------------------------------------*/72 942 73 943 static driver_t kbd_driver = { … … 76 946 }; 77 947 78 /*----------------------------------------------------------------------------*/79 80 948 int main(int argc, char *argv[]) 81 949 { -
uspace/lib/c/generic/loader.c
re135751 r51b46f2 160 160 int rc = async_data_write_start(ldr->phone_id, (void *) pa, pa_len); 161 161 if (rc != EOK) { 162 free(pa);163 162 async_wait_for(req, NULL); 164 163 return rc; -
uspace/lib/c/generic/vfs/vfs.c
re135751 r51b46f2 69 69 char *ncwd_path; 70 70 char *ncwd_path_nc; 71 size_t total_size;72 71 73 72 fibril_mutex_lock(&cwd_mutex); … … 78 77 return NULL; 79 78 } 80 total_size = cwd_size + 1 + size + 1; 81 ncwd_path_nc = malloc(total_size); 79 ncwd_path_nc = malloc(cwd_size + 1 + size + 1); 82 80 if (!ncwd_path_nc) { 83 81 fibril_mutex_unlock(&cwd_mutex); 84 82 return NULL; 85 83 } 86 str_cpy(ncwd_path_nc, total_size, cwd_path);84 str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path); 87 85 ncwd_path_nc[cwd_size] = '/'; 88 86 ncwd_path_nc[cwd_size + 1] = '\0'; 89 87 } else { 90 total_size = size + 1; 91 ncwd_path_nc = malloc(total_size); 88 ncwd_path_nc = malloc(size + 1); 92 89 if (!ncwd_path_nc) { 93 90 fibril_mutex_unlock(&cwd_mutex); … … 96 93 ncwd_path_nc[0] = '\0'; 97 94 } 98 str_append(ncwd_path_nc, total_size, path);95 str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path); 99 96 ncwd_path = canonify(ncwd_path_nc, retlen); 100 97 if (!ncwd_path) { -
uspace/lib/c/include/ipc/dev_iface.h
re135751 r51b46f2 38 38 CHAR_DEV_IFACE, 39 39 40 /** Interface provided by any PCI device. */41 PCI_DEV_IFACE,42 43 40 /** Interface provided by any USB device. */ 44 41 USB_DEV_IFACE, -
uspace/lib/drv/Makefile
re135751 r51b46f2 38 38 generic/remote_hw_res.c \ 39 39 generic/remote_usb.c \ 40 generic/remote_pci.c \41 40 generic/remote_usbhc.c 42 41 -
uspace/lib/drv/generic/dev_iface.c
re135751 r51b46f2 43 43 #include "remote_usb.h" 44 44 #include "remote_usbhc.h" 45 #include "remote_pci.h"46 45 47 46 static iface_dipatch_table_t remote_ifaces = { … … 49 48 &remote_hw_res_iface, 50 49 &remote_char_dev_iface, 51 &remote_pci_iface,52 50 &remote_usb_iface, 53 51 &remote_usbhc_iface -
uspace/srv/devmap/devmap.c
re135751 r51b46f2 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 can128 * be used just as any other devices, e.g. in devmap_device_unregister_core().129 */130 static LIST_INITIALIZE(dummy_null_driver_devices);131 125 132 126 static devmap_handle_t devmap_create_handle(void) … … 959 953 device->name = dev_name; 960 954 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 */ 955 /* Insert device into list of all devices 956 and into null devices array */ 966 957 list_append(&device->devices, &devices_list); 967 list_append(&device->driver_devices, &dummy_null_driver_devices);968 958 null_devices[i] = device; 969 959 -
uspace/srv/fs/fat/fat_ops.c
re135751 r51b46f2 325 325 uint16_t_le2host(d->firstc)); 326 326 if (rc != EOK) { 327 (void) block_put(b);328 327 (void) fat_node_put(FS_NODE(nodep)); 329 328 return rc; … … 812 811 fibril_mutex_unlock(&childp->idx->lock); 813 812 childp->lnkcnt = 0; 814 childp->refcnt++; /* keep the node in memory until destroyed */815 813 childp->dirty = true; 816 814 fibril_mutex_unlock(&childp->lock); … … 1490 1488 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1491 1489 fs_node_t *fn; 1492 fat_node_t *nodep;1493 1490 int rc; 1494 1491 … … 1502 1499 return; 1503 1500 } 1504 1505 nodep = FAT_NODE(fn);1506 /*1507 * We should have exactly two references. One for the above1508 * call to fat_node_get() and one from fat_unlink().1509 */1510 assert(nodep->refcnt == 2);1511 1501 1512 1502 rc = fat_destroy_node(fn);
Note:
See TracChangeset
for help on using the changeset viewer.