Changes in / [8c877b2:dff940f8] in mainline
- Files:
-
- 3 added
- 18 deleted
- 57 edited
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
r8c877b2 rdff940f8 89 89 ./uspace/drv/usbhid/usbhid 90 90 ./uspace/drv/usbmid/usbmid 91 ./uspace/drv/usbmouse/usbmouse92 91 ./uspace/drv/vhc/vhc 93 92 ./uspace/srv/bd/ata_bd/ata_bd -
Makefile
r8c877b2 rdff940f8 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/amd64/Makefile.inc
r8c877b2 rdff940f8 48 48 usbhid \ 49 49 usbmid \ 50 usbmouse \51 50 vhc 52 51 -
boot/arch/sparc64/include/arch.h
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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/Makefile
r8c877b2 rdff940f8 122 122 drv/usbhub \ 123 123 drv/usbmid \ 124 drv/usbmouse \125 124 drv/vhc 126 125 endif … … 139 138 drv/usbhub \ 140 139 drv/usbmid \ 141 drv/usbmouse \142 140 drv/vhc 143 141 endif -
uspace/app/bdsh/cmds/modules/mount/mount.c
r8c877b2 rdff940f8 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/doc/doxygroups.h
r8c877b2 rdff940f8 245 245 246 246 /** 247 * @defgroup drvusbmouse USB mouse driver248 * @ingroup usb249 * @brief USB driver for mouse with boot protocol.250 */251 252 /**253 247 * @defgroup drvusbuhci UHCI driver 254 248 * @ingroup usb -
uspace/drv/pciintel/pci.c
r8c877b2 rdff940f8 59 59 #include <ddi.h> 60 60 #include <libarch/ddi.h> 61 #include <pci_dev_iface.h>62 61 63 62 #include "pci.h" … … 94 93 sysarg_t apic; 95 94 sysarg_t i8259; 96 97 95 int irc_phone = -1; 98 96 int irc_service = 0; … … 104 102 } 105 103 106 if (irc_service == 0) 104 if (irc_service) { 105 while (irc_phone < 0) 106 irc_phone = service_connect_blocking(irc_service, 0, 0); 107 } else { 107 108 return false; 108 109 irc_phone = service_connect_blocking(irc_service, 0, 0); 110 if (irc_phone < 0) 111 return false; 109 } 112 110 113 111 size_t i; … … 115 113 if (dev_data->hw_resources.resources[i].type == INTERRUPT) { 116 114 int irq = dev_data->hw_resources.resources[i].res.interrupt.irq; 117 int rc = async_req_1_0(irc_phone, IRC_ENABLE_INTERRUPT, irq); 118 if (rc != EOK) { 119 async_hangup(irc_phone); 120 return false; 121 } 115 async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq); 122 116 } 123 117 } … … 126 120 return true; 127 121 } 128 129 static int pci_config_space_write_16(ddf_fun_t *fun, uint32_t address, uint16_t data)130 {131 if (address > 254)132 return EINVAL;133 pci_conf_write_16(PCI_FUN(fun), address, data);134 return EOK;135 }136 137 122 138 123 static hw_res_ops_t pciintel_hw_res_ops = { … … 141 126 }; 142 127 143 static pci_dev_iface_t pci_dev_ops = { 144 .config_space_read_8 = NULL, 145 .config_space_read_16 = NULL, 146 .config_space_read_32 = NULL, 147 .config_space_write_8 = NULL, 148 .config_space_write_16 = &pci_config_space_write_16, 149 .config_space_write_32 = NULL 150 }; 151 152 static ddf_dev_ops_t pci_fun_ops = { 153 .interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops, 154 .interfaces[PCI_DEV_IFACE] = &pci_dev_ops 155 }; 128 static ddf_dev_ops_t pci_fun_ops; 156 129 157 130 static int pci_add_device(ddf_dev_t *); … … 347 320 /* Get the value of the BAR. */ 348 321 val = pci_conf_read_32(fun, addr); 349 350 #define IO_MASK (~0x3)351 #define MEM_MASK (~0xf)352 322 353 323 io = (bool) (val & 1); 354 324 if (io) { 355 325 addrw64 = false; 356 mask = IO_MASK;357 326 } else { 358 mask = MEM_MASK;359 327 switch ((val >> 1) & 3) { 360 328 case 0: … … 372 340 /* Get the address mask. */ 373 341 pci_conf_write_32(fun, addr, 0xffffffff); 374 mask &= pci_conf_read_32(fun, addr);342 mask = pci_conf_read_32(fun, addr); 375 343 376 344 /* Restore the original value. */ … … 620 588 { 621 589 pci_fun_ops.interfaces[HW_RES_DEV_IFACE] = &pciintel_hw_res_ops; 622 pci_fun_ops.interfaces[PCI_DEV_IFACE] = &pci_dev_ops;623 590 } 624 591 … … 692 659 size_t pci_bar_mask_to_size(uint32_t mask) 693 660 { 694 size_t size = mask & ~(mask - 1); 695 return size; 661 return ((mask & 0xfffffff0) ^ 0xffffffff) + 1; 696 662 } 697 663 -
uspace/drv/uhci-hcd/Makefile
r8c877b2 rdff940f8 39 39 uhci.c \ 40 40 uhci_struct/transfer_descriptor.c \ 41 utils/device_keeper.c \42 41 pci.c \ 43 42 batch.c -
uspace/drv/uhci-hcd/batch.c
r8c877b2 rdff940f8 33 33 */ 34 34 #include <errno.h> 35 #include <str_error.h> 36 37 #include <usb/usb.h> 35 38 36 #include <usb/debug.h> 39 37 … … 47 45 static int batch_schedule(batch_t *instance); 48 46 49 static void batch_control(50 batch_t *instance, int data_stage, int status_stage);51 47 static void batch_call_in(batch_t *instance); 52 48 static void batch_call_out(batch_t *instance); … … 57 53 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target, 58 54 usb_transfer_type_t transfer_type, size_t max_packet_size, 59 usb_speed_t speed, char *buffer, size_t size,55 dev_speed_t speed, char *buffer, size_t size, 60 56 char* setup_buffer, size_t setup_size, 61 57 usbhc_iface_transfer_in_callback_t func_in, … … 96 92 instance->transport_buffer = 97 93 (size > 0) ? malloc32(transport_size) : NULL; 98 99 94 if ((size > 0) && (instance->transport_buffer == NULL)) { 100 95 usb_log_error("Failed to allocate device accessible buffer.\n"); … … 138 133 139 134 queue_head_element_td(instance->qh, addr_to_phys(instance->tds)); 140 usb_log_debug("Batch(%p) %d:%d memory structures ready.\n",141 instance, target.address, target.endpoint);142 135 return instance; 143 136 } … … 146 139 { 147 140 assert(instance); 148 usb_log_debug 2("Batch(%p) checking %d packet(s)for completion.\n",141 usb_log_debug("Checking(%p) %d packet for completion.\n", 149 142 instance, instance->packets); 150 143 instance->transfered_size = 0; … … 158 151 if (i > 0) 159 152 instance->transfered_size -= instance->setup_size; 160 usb_log_debug("Batch(%p) found error TD(%d):%x.\n",161 instance, i, instance->tds[i].status);162 153 return true; 163 154 } … … 165 156 transfer_descriptor_actual_size(&instance->tds[i]); 166 157 } 158 /* This is just an ugly trick to support the old API */ 167 159 instance->transfered_size -= instance->setup_size; 168 160 return true; … … 172 164 { 173 165 assert(instance); 166 174 167 /* we are data out, we are supposed to provide data */ 175 168 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 176 batch_control(instance, USB_PID_OUT, USB_PID_IN); 169 170 int toggle = 0; 171 /* setup stage */ 172 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 173 instance->setup_size, toggle, false, instance->target, 174 USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]); 175 176 /* data stage */ 177 size_t i = 1; 178 for (;i < instance->packets - 1; ++i) { 179 char *data = 180 instance->transport_buffer + ((i - 1) * instance->max_packet_size); 181 toggle = 1 - toggle; 182 183 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 184 instance->max_packet_size, toggle++, false, instance->target, 185 USB_PID_OUT, data, &instance->tds[i + 1]); 186 } 187 188 /* status stage */ 189 i = instance->packets - 1; 190 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 191 0, 1, false, instance->target, USB_PID_IN, NULL, NULL); 192 193 instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 194 177 195 instance->next_step = batch_call_out_and_dispose; 178 usb_log_debug("Batch(%p) CONTROL WRITE initialized.\n", instance);179 196 batch_schedule(instance); 180 197 } … … 183 200 { 184 201 assert(instance); 185 batch_control(instance, USB_PID_IN, USB_PID_OUT); 202 203 int toggle = 0; 204 /* setup stage */ 205 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 206 instance->setup_size, toggle, false, instance->target, 207 USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]); 208 209 /* data stage */ 210 size_t i = 1; 211 for (;i < instance->packets - 1; ++i) { 212 char *data = 213 instance->transport_buffer + ((i - 1) * instance->max_packet_size); 214 toggle = 1 - toggle; 215 216 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 217 instance->max_packet_size, toggle, false, instance->target, 218 USB_PID_IN, data, &instance->tds[i + 1]); 219 } 220 221 /* status stage */ 222 i = instance->packets - 1; 223 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 224 0, 1, false, instance->target, USB_PID_OUT, NULL, NULL); 225 226 instance->tds[i].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 227 186 228 instance->next_step = batch_call_in_and_dispose; 187 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance);188 229 batch_schedule(instance); 189 230 } … … 193 234 assert(instance); 194 235 195 const bool low_speed = instance->speed == USB_SPEED_LOW;196 236 int toggle = 1; 197 237 size_t i = 0; … … 204 244 205 245 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 206 instance->max_packet_size, toggle, false, low_speed,207 instance->target,USB_PID_IN, data, next);246 instance->max_packet_size, toggle, false, instance->target, 247 USB_PID_IN, data, next); 208 248 } 209 249 … … 211 251 212 252 instance->next_step = batch_call_in_and_dispose; 213 usb_log_debug("Batch(%p) INTERRUPT IN initialized.\n", instance);214 253 batch_schedule(instance); 215 254 } … … 218 257 { 219 258 assert(instance); 259 220 260 memcpy(instance->transport_buffer, instance->buffer, instance->buffer_size); 221 261 222 const bool low_speed = instance->speed == USB_SPEED_LOW;223 262 int toggle = 1; 224 263 size_t i = 0; … … 231 270 232 271 transfer_descriptor_init(&instance->tds[i], DEFAULT_ERROR_COUNT, 233 instance->max_packet_size, toggle++, false, low_speed,234 instance->target,USB_PID_OUT, data, next);272 instance->max_packet_size, toggle++, false, instance->target, 273 USB_PID_OUT, data, next); 235 274 } 236 275 … … 238 277 239 278 instance->next_step = batch_call_out_and_dispose; 240 usb_log_debug("Batch(%p) INTERRUPT OUT initialized.\n", instance); 241 batch_schedule(instance); 242 } 243 /*----------------------------------------------------------------------------*/ 244 static void batch_control( 245 batch_t *instance, int data_stage, int status_stage) 246 { 247 assert(instance); 248 249 const bool low_speed = instance->speed == USB_SPEED_LOW; 250 int toggle = 0; 251 /* setup stage */ 252 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 253 instance->setup_size, toggle, false, low_speed, instance->target, 254 USB_PID_SETUP, instance->setup_buffer, &instance->tds[1]); 255 256 /* data stage */ 257 size_t packet = 1; 258 size_t remain_size = instance->buffer_size; 259 while (remain_size > 0) { 260 char *data = 261 instance->transport_buffer + instance->buffer_size 262 - remain_size; 263 264 toggle = 1 - toggle; 265 266 const size_t packet_size = 267 (instance->max_packet_size > remain_size) ? 268 remain_size : instance->max_packet_size; 269 270 transfer_descriptor_init(&instance->tds[packet], 271 DEFAULT_ERROR_COUNT, packet_size, toggle, false, low_speed, 272 instance->target, data_stage, data, 273 &instance->tds[packet + 1]); 274 275 ++packet; 276 assert(packet < instance->packets); 277 assert(packet_size <= remain_size); 278 remain_size -= packet_size; 279 } 280 281 /* status stage */ 282 assert(packet == instance->packets - 1); 283 transfer_descriptor_init(&instance->tds[packet], DEFAULT_ERROR_COUNT, 284 0, 1, false, low_speed, instance->target, status_stage, NULL, NULL); 285 286 287 instance->tds[packet].status |= TD_STATUS_COMPLETE_INTERRUPT_FLAG; 288 usb_log_debug2("Control last TD status: %x.\n", 289 instance->tds[packet].status); 279 batch_schedule(instance); 290 280 } 291 281 /*----------------------------------------------------------------------------*/ … … 298 288 299 289 int err = instance->error; 300 usb_log_debug("Batch(%p) callback IN(type:%d): %s(%d), %zu.\n", 301 instance, instance->transfer_type, str_error(err), err, 302 instance->transfered_size); 290 usb_log_info("Callback IN(%d): %d, %zu.\n", instance->transfer_type, 291 err, instance->transfered_size); 303 292 304 293 instance->callback_in(instance->fun, … … 313 302 314 303 int err = instance->error; 315 usb_log_debug("Batch(%p) callback OUT(type:%d): %s(%d).\n", 316 instance, instance->transfer_type, str_error(err), err); 304 usb_log_info("Callback OUT(%d): %d.\n", instance->transfer_type, err); 317 305 instance->callback_out(instance->fun, 318 306 err, instance->arg); … … 323 311 assert(instance); 324 312 batch_call_in(instance); 325 usb_log_debug(" Batch(%p) disposing.\n", instance);313 usb_log_debug("Disposing batch: %p.\n", instance); 326 314 free32(instance->tds); 327 315 free32(instance->qh); … … 335 323 assert(instance); 336 324 batch_call_out(instance); 337 usb_log_debug(" Batch(%p) disposing.\n", instance);325 usb_log_debug("Disposing batch: %p.\n", instance); 338 326 free32(instance->tds); 339 327 free32(instance->qh); … … 350 338 return uhci_schedule(hc, instance); 351 339 } 340 /*----------------------------------------------------------------------------*/ 341 /* DEPRECATED FUNCTIONS NEEDED BY THE OLD API */ 342 void batch_control_setup_old(batch_t *instance) 343 { 344 assert(instance); 345 instance->packets = 1; 346 347 /* setup stage */ 348 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 349 instance->setup_size, 0, false, instance->target, 350 USB_PID_SETUP, instance->setup_buffer, NULL); 351 352 instance->next_step = batch_call_out_and_dispose; 353 batch_schedule(instance); 354 } 355 /*----------------------------------------------------------------------------*/ 356 void batch_control_write_data_old(batch_t *instance) 357 { 358 assert(instance); 359 instance->packets -= 2; 360 batch_interrupt_out(instance); 361 } 362 /*----------------------------------------------------------------------------*/ 363 void batch_control_read_data_old(batch_t *instance) 364 { 365 assert(instance); 366 instance->packets -= 2; 367 batch_interrupt_in(instance); 368 } 369 /*----------------------------------------------------------------------------*/ 370 void batch_control_write_status_old(batch_t *instance) 371 { 372 assert(instance); 373 instance->packets = 1; 374 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 375 0, 1, false, instance->target, USB_PID_IN, NULL, NULL); 376 instance->next_step = batch_call_in_and_dispose; 377 batch_schedule(instance); 378 } 379 /*----------------------------------------------------------------------------*/ 380 void batch_control_read_status_old(batch_t *instance) 381 { 382 assert(instance); 383 instance->packets = 1; 384 transfer_descriptor_init(instance->tds, DEFAULT_ERROR_COUNT, 385 0, 1, false, instance->target, USB_PID_OUT, NULL, NULL); 386 instance->next_step = batch_call_out_and_dispose; 387 batch_schedule(instance); 388 } 352 389 /** 353 390 * @} -
uspace/drv/uhci-hcd/batch.h
r8c877b2 rdff940f8 43 43 #include "uhci_struct/queue_head.h" 44 44 45 typedef enum { 46 LOW_SPEED, 47 FULL_SPEED, 48 } dev_speed_t; 49 45 50 typedef struct batch 46 51 { 47 52 link_t link; 48 usb_speed_t speed;53 dev_speed_t speed; 49 54 usb_target_t target; 50 55 usb_transfer_type_t transfer_type; … … 71 76 batch_t * batch_get(ddf_fun_t *fun, usb_target_t target, 72 77 usb_transfer_type_t transfer_type, size_t max_packet_size, 73 usb_speed_t speed, char *buffer, size_t size,78 dev_speed_t speed, char *buffer, size_t size, 74 79 char *setup_buffer, size_t setup_size, 75 80 usbhc_iface_transfer_in_callback_t func_in, -
uspace/drv/uhci-hcd/iface.c
r8c877b2 rdff940f8 41 41 #include "iface.h" 42 42 #include "uhci.h" 43 #include "utils/device_keeper.h"44 43 45 44 /*----------------------------------------------------------------------------*/ … … 49 48 uhci_t *hc = fun_to_uhci(fun); 50 49 assert(hc); 51 usb_log_debug("Default address request with speed %d.\n", speed); 52 device_keeper_reserve_default(&hc->device_manager, speed); 50 usb_address_keeping_reserve_default(&hc->address_manager); 53 51 return EOK; 54 52 } … … 59 57 uhci_t *hc = fun_to_uhci(fun); 60 58 assert(hc); 61 usb_log_debug("Default address release.\n"); 62 device_keeper_release_default(&hc->device_manager); 59 usb_address_keeping_release_default(&hc->address_manager); 63 60 return EOK; 64 61 } … … 70 67 uhci_t *hc = fun_to_uhci(fun); 71 68 assert(hc); 72 assert(address); 73 74 usb_log_debug("Address request with speed %d.\n", speed); 75 *address = device_keeper_request(&hc->device_manager, speed); 76 usb_log_debug("Address request with result: %d.\n", *address); 69 *address = usb_address_keeping_request(&hc->address_manager); 77 70 if (*address <= 0) 78 71 return *address; … … 86 79 uhci_t *hc = fun_to_uhci(fun); 87 80 assert(hc); 88 usb_log_debug("Address bind %d-%d.\n", address, handle); 89 device_keeper_bind(&hc->device_manager, address, handle); 81 usb_address_keeping_devman_bind(&hc->address_manager, address, handle); 90 82 return EOK; 91 83 } … … 96 88 uhci_t *hc = fun_to_uhci(fun); 97 89 assert(hc); 98 usb_log_debug("Address release %d.\n", address); 99 device_keeper_release(&hc->device_manager, address); 90 usb_address_keeping_release_default(&hc->address_manager); 100 91 return EOK; 101 92 } 102 93 /*----------------------------------------------------------------------------*/ 103 94 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 104 size_t max_packet_size, void *data, size_t size, 95 size_t max_packet_size, 96 void *data, size_t size, 105 97 usbhc_iface_transfer_out_callback_t callback, void *arg) 106 98 { 107 assert(fun); 108 uhci_t *hc = fun_to_uhci(fun); 109 assert(hc); 110 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 111 112 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 113 target.address, target.endpoint, size, max_packet_size); 99 dev_speed_t speed = FULL_SPEED; 114 100 115 101 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, … … 122 108 /*----------------------------------------------------------------------------*/ 123 109 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 124 size_t max_packet_size, void *data, size_t size, 110 size_t max_packet_size, 111 void *data, size_t size, 125 112 usbhc_iface_transfer_in_callback_t callback, void *arg) 126 113 { 127 assert(fun); 128 uhci_t *hc = fun_to_uhci(fun); 129 assert(hc); 130 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 131 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 132 target.address, target.endpoint, size, max_packet_size); 114 dev_speed_t speed = FULL_SPEED; 133 115 134 116 batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, … … 145 127 usbhc_iface_transfer_out_callback_t callback, void *arg) 146 128 { 147 assert(fun); 148 uhci_t *hc = fun_to_uhci(fun); 149 assert(hc); 150 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 151 usb_log_debug("Control WRITE %d:%d %zu(%zu).\n", 152 target.address, target.endpoint, size, max_packet_size); 129 dev_speed_t speed = FULL_SPEED; 153 130 154 131 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, … … 166 143 usbhc_iface_transfer_in_callback_t callback, void *arg) 167 144 { 168 assert(fun); 169 uhci_t *hc = fun_to_uhci(fun); 170 assert(hc); 171 usb_speed_t speed = device_keeper_speed(&hc->device_manager, target.address); 145 dev_speed_t speed = FULL_SPEED; 172 146 173 usb_log_debug("Control READ %d:%d %zu(%zu).\n",174 target.address, target.endpoint, size, max_packet_size);175 147 batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 176 148 max_packet_size, speed, data, size, setup_data, setup_size, callback, -
uspace/drv/uhci-hcd/main.c
r8c877b2 rdff940f8 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"); 84 83 85 uintptr_t io_reg_base = 0; 86 size_t io_reg_size = 0; 87 int irq = 0; 84 85 uintptr_t io_reg_base; 86 size_t io_reg_size; 87 int irq; 88 88 89 89 int ret = 90 90 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq); 91 CHECK_RET_FREE_HC_RETURN(ret, 91 92 CHECK_RET_RETURN(ret, 92 93 "Failed(%d) to get I/O addresses:.\n", ret, device->handle); 93 94 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n", 94 95 io_reg_base, io_reg_size, irq); 95 96 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)); 97 ret = pci_enable_interrupts(device); 98 CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret); 99 99 100 #if 0 101 ret = pci_enable_interrupts(device); 100 uhci_t *uhci_hc = malloc(sizeof(uhci_t)); 101 ret = (uhci_hc != NULL) ? EOK : ENOMEM; 102 CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n"); 103 104 ret = uhci_init(uhci_hc, device, (void*)io_reg_base, io_reg_size); 102 105 if (ret != EOK) { 103 usb_log_ warning(104 "Failed(%d) to enable interrupts, fall back to polling.\n",105 ret);106 usb_log_error("Failed to init uhci-hcd.\n"); 107 free(uhci_hc); 108 return ret; 106 109 } 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 110 119 111 /* 120 * We might free hcd, but that does not matter since no one112 * We might free uhci_hc, but that does not matter since no one 121 113 * else would access driver_data anyway. 122 114 */ 123 device->driver_data = hcd;115 device->driver_data = uhci_hc; 124 116 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 } 117 ret = register_interrupt_handler(device, irq, irq_handler, 118 &uhci_hc->interrupt_code); 119 if (ret != EOK) { 120 usb_log_error("Failed to register interrupt handler.\n"); 121 uhci_fini(uhci_hc); 122 free(uhci_hc); 123 return ret; 124 } 137 125 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 126 ddf_fun_t *rh; 144 127 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; 128 if (ret != EOK) { 129 usb_log_error("Failed to setup uhci root hub.\n"); 130 uhci_fini(uhci_hc); 131 free(uhci_hc); 132 return ret; 133 } 134 rh->driver_data = uhci_hc->ddf_instance; 148 135 149 136 ret = ddf_fun_bind(rh); 150 CHECK_RET_FINI_FREE_RETURN(ret, 151 "Failed(%d) to register UHCI root hub.\n", ret); 137 if (ret != EOK) { 138 usb_log_error("Failed to register root hub.\n"); 139 uhci_fini(uhci_hc); 140 free(uhci_hc); 141 free(rh); 142 return ret; 143 } 152 144 153 145 return EOK; 154 #undef CHECK_RET_FINI_FREE_RETURN155 146 } 156 147 /*----------------------------------------------------------------------------*/ … … 158 149 { 159 150 sleep(3); 160 usb_log_enable(USB_LOG_LEVEL_ DEBUG, NAME);151 usb_log_enable(USB_LOG_LEVEL_INFO, NAME); 161 152 162 153 return ddf_driver_main(&uhci_driver); -
uspace/drv/uhci-hcd/pci.c
r8c877b2 rdff940f8 38 38 #include <devman.h> 39 39 #include <device/hw_res.h> 40 41 #include <usb/debug.h>42 #include <pci_dev_iface.h>43 40 44 41 #include "pci.h" … … 86 83 irq = res->res.interrupt.irq; 87 84 irq_found = true; 88 usb_log_debug2("Found interrupt: %d.\n", irq);89 85 break; 90 86 case IO_RANGE: 91 io_address = res->res.io_range.address; 87 io_address = (uintptr_t) 88 res->res.io_range.address; 92 89 io_size = res->res.io_range.size; 93 usb_log_debug2("Found io: %llx %zu.\n",94 res->res.io_range.address, res->res.io_range.size);95 90 io_found = true; 96 91 break; … … 110 105 } 111 106 112 *io_reg_address = io_address; 113 *io_reg_size = io_size; 114 *irq_no = irq; 107 if (io_reg_address != NULL) { 108 *io_reg_address = io_address; 109 } 110 if (io_reg_size != NULL) { 111 *io_reg_size = io_size; 112 } 113 if (irq_no != NULL) { 114 *irq_no = irq; 115 } 115 116 116 117 rc = EOK; … … 126 127 IPC_FLAG_BLOCKING); 127 128 bool enabled = hw_res_enable_interrupt(parent_phone); 128 async_hangup(parent_phone);129 129 return enabled ? EOK : EIO; 130 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 /*----------------------------------------------------------------------------*/153 131 /** 154 132 * @} -
uspace/drv/uhci-hcd/pci.h
r8c877b2 rdff940f8 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/root_hub.c
r8c877b2 rdff940f8 34 34 #include <assert.h> 35 35 #include <errno.h> 36 #include <str_error.h>37 36 #include <stdio.h> 38 #include <ops/hw_res.h>39 40 37 #include <usb_iface.h> 41 38 #include <usb/debug.h> … … 44 41 #include "uhci.h" 45 42 46 /*----------------------------------------------------------------------------*/47 43 static int usb_iface_get_hc_handle_rh_impl(ddf_fun_t *root_hub_fun, 48 44 devman_handle_t *handle) … … 55 51 return EOK; 56 52 } 57 /*----------------------------------------------------------------------------*/ 53 58 54 static int usb_iface_get_address_rh_impl(ddf_fun_t *fun, devman_handle_t handle, 59 55 usb_address_t *address) … … 65 61 assert(hc); 66 62 67 usb_address_t addr = device_keeper_find(&hc->device_manager,63 usb_address_t addr = usb_address_keeping_find(&hc->address_manager, 68 64 handle); 69 65 if (addr < 0) { … … 77 73 return EOK; 78 74 } 79 /*----------------------------------------------------------------------------*/ 75 80 76 usb_iface_t usb_iface_root_hub_fun_impl = { 81 77 .get_hc_handle = usb_iface_get_hc_handle_rh_impl, 82 78 .get_address = usb_iface_get_address_rh_impl 83 79 }; 84 /*----------------------------------------------------------------------------*/85 static hw_resource_list_t *get_resource_list(ddf_fun_t *dev)86 {87 assert(dev);88 ddf_fun_t *hc_ddf_instance = dev->driver_data;89 assert(hc_ddf_instance);90 uhci_t *hc = hc_ddf_instance->driver_data;91 assert(hc);92 80 93 //TODO: fix memory leak 94 hw_resource_list_t *resource_list = malloc(sizeof(hw_resource_list_t)); 95 assert(resource_list); 96 resource_list->count = 1; 97 resource_list->resources = malloc(sizeof(hw_resource_t)); 98 assert(resource_list->resources); 99 resource_list->resources[0].type = IO_RANGE; 100 resource_list->resources[0].res.io_range.address = 101 ((uintptr_t)hc->registers) + 0x10; // see UHCI design guide 102 resource_list->resources[0].res.io_range.size = 4; 103 resource_list->resources[0].res.io_range.endianness = LITTLE_ENDIAN; 81 static ddf_dev_ops_t root_hub_ops = { 82 .interfaces[USB_DEV_IFACE] = &usb_iface_root_hub_fun_impl 83 }; 104 84 105 return resource_list;106 }107 /*----------------------------------------------------------------------------*/108 static hw_res_ops_t hw_res_iface = {109 .get_resource_list = get_resource_list,110 .enable_interrupt = NULL111 };112 /*----------------------------------------------------------------------------*/113 static ddf_dev_ops_t root_hub_ops = {114 .interfaces[USB_DEV_IFACE] = &usb_iface_root_hub_fun_impl,115 .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface116 };117 85 /*----------------------------------------------------------------------------*/ 118 86 int setup_root_hub(ddf_fun_t **fun, ddf_dev_t *hc) 119 87 { 120 88 assert(fun); 121 assert(hc);122 89 int ret; 123 90 … … 138 105 ret = ddf_fun_add_match_id(hub, match_str, 100); 139 106 if (ret != EOK) { 140 usb_log_error("Failed(%d) to add root hub match id: %s\n", 141 ret, str_error(ret)); 107 usb_log_error("Failed to add root hub match id.\n"); 142 108 ddf_fun_destroy(hub); 143 return ret;109 return ENOMEM; 144 110 } 145 111 -
uspace/drv/uhci-hcd/transfer_list.c
r8c877b2 rdff940f8 70 70 assert(instance); 71 71 assert(batch); 72 usb_log_debug2("Adding batch(%p) to queue %s.\n", batch, instance->name);73 72 74 73 uint32_t pa = (uintptr_t)addr_to_phys(batch->qh); … … 84 83 list_append(&batch->link, &instance->batch_list); 85 84 instance->queue_head->element = pa; 86 usb_log_debug ("Batch(%p) addedto queue %s first.\n",85 usb_log_debug2("Added batch(%p) to queue %s first.\n", 87 86 batch, instance->name); 88 87 fibril_mutex_unlock(&instance->guard); … … 97 96 queue_head_append_qh(last->qh, pa); 98 97 list_append(&batch->link, &instance->batch_list); 99 usb_log_debug ("Batch(%p) addedto queue %s last, first is %p.\n",98 usb_log_debug2("Added batch(%p) to queue %s last, first is %p.\n", 100 99 batch, instance->name, first ); 101 100 fibril_mutex_unlock(&instance->guard); … … 109 108 assert(instance->queue_head); 110 109 assert(batch->qh); 111 usb_log_debug2("Removing batch(%p) from queue %s.\n", batch, instance->name);112 110 113 111 /* I'm the first one here */ 114 112 if (batch->link.prev == &instance->batch_list) { 115 usb_log_debug(" Batch(%p) removed (FIRST) from queue %s, next element %x.\n",116 batch, instance->name,batch->qh->next_queue);113 usb_log_debug("Removing batch %p was first, next element %x.\n", 114 batch, batch->qh->next_queue); 117 115 instance->queue_head->element = batch->qh->next_queue; 118 116 } else { 119 usb_log_debug(" Batch(%p) removed (NOT FIRST) from queue, next element %x.\n",120 batch, instance->name,batch->qh->next_queue);117 usb_log_debug("Removing batch %p was NOT first, next element %x.\n", 118 batch, batch->qh->next_queue); 121 119 batch_t *prev = list_get_instance(batch->link.prev, batch_t, link); 122 120 prev->qh->next_queue = batch->qh->next_queue; … … 125 123 } 126 124 /*----------------------------------------------------------------------------*/ 127 void transfer_list_ remove_finished(transfer_list_t *instance)125 void transfer_list_check(transfer_list_t *instance) 128 126 { 129 127 assert(instance); 130 131 LIST_INITIALIZE(done);132 133 128 fibril_mutex_lock(&instance->guard); 134 129 link_t *current = instance->batch_list.next; … … 139 134 if (batch_is_complete(batch)) { 140 135 transfer_list_remove_batch(instance, batch); 141 list_append(current, &done);136 batch->next_step(batch); 142 137 } 143 138 current = next; 144 139 } 145 140 fibril_mutex_unlock(&instance->guard); 146 147 while (!list_empty(&done)) {148 link_t *item = done.next;149 list_remove(item);150 batch_t *batch = list_get_instance(item, batch_t, link);151 batch->next_step(batch);152 }153 141 } 154 142 /** -
uspace/drv/uhci-hcd/transfer_list.h
r8c877b2 rdff940f8 60 60 queue_head_dispose(instance->queue_head); 61 61 } 62 void transfer_list_ remove_finished(transfer_list_t *instance);62 void transfer_list_check(transfer_list_t *instance); 63 63 64 64 void transfer_list_add_batch(transfer_list_t *instance, batch_t *batch); -
uspace/drv/uhci-hcd/uhci-hcd.ma
r8c877b2 rdff940f8 1 1 10 pci/ven=8086&dev=7020 2 2 10 pci/ven=8086&dev=7112 3 4 10 pci/ven=8086&dev=27c85 10 pci/ven=8086&dev=27c96 10 pci/ven=8086&dev=27ca7 10 pci/ven=8086&dev=27cb8 9 10 10 pci/ven=8086&dev=283011 10 pci/ven=8086&dev=283112 10 pci/ven=8086&dev=283213 10 pci/ven=8086&dev=283414 10 pci/ven=8086&dev=283515 16 10 pci/ven=8086&dev=293417 10 pci/ven=8086&dev=293518 10 pci/ven=8086&dev=293619 10 pci/ven=8086&dev=293720 10 pci/ven=8086&dev=293821 10 pci/ven=8086&dev=2939 -
uspace/drv/uhci-hcd/uhci.c
r8c877b2 rdff940f8 48 48 { 49 49 .cmd = CMD_PIO_READ_16, 50 .addr = NULL, /* patched for every instance */50 .addr = (void*)0xc022, 51 51 .dstarg = 1 52 52 }, 53 53 { 54 54 .cmd = CMD_PIO_WRITE_16, 55 .addr = NULL, /* pathed for every instance */55 .addr = (void*)0xc022, 56 56 .value = 0x1f 57 57 }, … … 68 68 assert(hc); 69 69 70 usb_address_t addr = device_keeper_find(&hc->device_manager,70 usb_address_t addr = usb_address_keeping_find(&hc->address_manager, 71 71 handle); 72 72 if (addr < 0) { … … 80 80 return EOK; 81 81 } 82 /*----------------------------------------------------------------------------*/ 82 83 83 84 static usb_iface_t hc_usb_iface = { 84 85 .get_hc_handle = usb_iface_get_hc_handle_hc_impl, … … 88 89 static ddf_dev_ops_t uhci_ops = { 89 90 .interfaces[USB_DEV_IFACE] = &hc_usb_iface, 90 .interfaces[USBHC_DEV_IFACE] = &uhci_iface ,91 .interfaces[USBHC_DEV_IFACE] = &uhci_iface 91 92 }; 92 /*----------------------------------------------------------------------------*/ 93 93 94 static int uhci_init_transfer_lists(uhci_t *instance); 94 95 static int uhci_init_mem_structures(uhci_t *instance); … … 101 102 bool low_speed, usb_transfer_type_t, size_t size); 102 103 104 #define CHECK_RET_RETURN(ret, message...) \ 105 if (ret != EOK) { \ 106 usb_log_error(message); \ 107 return ret; \ 108 } else (void) 0 103 109 104 110 int uhci_init(uhci_t *instance, ddf_dev_t *dev, void *regs, size_t reg_size) … … 107 113 int ret; 108 114 109 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \ 110 if (ret != EOK) { \ 111 usb_log_error(message); \ 112 if (instance->ddf_instance) \ 113 ddf_fun_destroy(instance->ddf_instance); \ 114 return ret; \ 115 } else (void) 0 116 117 /* Create UHCI function. */ 115 /* 116 * Create UHCI function. 117 */ 118 118 instance->ddf_instance = ddf_fun_create(dev, fun_exposed, "uhci"); 119 ret = (instance->ddf_instance == NULL) ? ENOMEM : EOK;120 CHECK_RET_DEST_FUN_RETURN(ret,121 "Failed to create UHCI device function.\n");122 119 if (instance->ddf_instance == NULL) { 120 usb_log_error("Failed to create UHCI device function.\n"); 121 return ENOMEM; 122 } 123 123 instance->ddf_instance->ops = &uhci_ops; 124 124 instance->ddf_instance->driver_data = instance; 125 125 126 126 ret = ddf_fun_bind(instance->ddf_instance); 127 CHECK_RET_DEST_FUN_RETURN(ret, 128 "Failed(%d) to bind UHCI device function: %s.\n", 129 ret, str_error(ret)); 127 CHECK_RET_RETURN(ret, "Failed to bind UHCI device function: %s.\n", 128 str_error(ret)); 130 129 131 130 /* allow access to hc control registers */ 132 131 regs_t *io; 133 132 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", 136 ret, str_error(ret), io); 133 CHECK_RET_RETURN(ret, "Failed to gain access to registers at %p.\n", io); 137 134 instance->registers = io; 138 usb_log_debug("Device registers at %p(%u) accessible.\n", 139 io, reg_size); 135 usb_log_debug("Device registers accessible.\n"); 140 136 141 137 ret = uhci_init_mem_structures(instance); 142 CHECK_RET_DEST_FUN_RETURN(ret, 143 "Failed to initialize UHCI memory structures.\n"); 138 CHECK_RET_RETURN(ret, "Failed to initialize memory structures.\n"); 144 139 145 140 uhci_init_hw(instance); 146 instance->cleaner = 147 148 fibril_add_ready(instance->cleaner);141 142 instance->cleaner = fibril_create(uhci_interrupt_emulator, instance); 143 // fibril_add_ready(instance->cleaner); 149 144 150 145 instance->debug_checker = fibril_create(uhci_debug_checker, instance); 151 146 fibril_add_ready(instance->debug_checker); 152 147 153 usb_log_info("Started UHCI driver.\n"); 154 return EOK; 155 #undef CHECK_RET_DEST_FUN_RETURN 148 return EOK; 156 149 } 157 150 /*----------------------------------------------------------------------------*/ 158 151 void uhci_init_hw(uhci_t *instance) 159 152 { 160 assert(instance);161 162 /* reset everything, who knows what touched it before us */163 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_GLOBAL_RESET);164 async_usleep(10000); /* 10ms according to USB spec */165 pio_write_16(&instance->registers->usbcmd, 0);166 167 /* reset hc, all states and counters */168 pio_write_16(&instance->registers->usbcmd, UHCI_CMD_HCRESET);169 while ((pio_read_16(&instance->registers->usbcmd) & UHCI_CMD_HCRESET) != 0)170 { async_usleep(10); }171 153 172 154 /* set framelist pointer */ … … 176 158 /* enable all interrupts, but resume interrupt */ 177 159 pio_write_16(&instance->registers->usbintr, 178 160 UHCI_INTR_CRC | UHCI_INTR_COMPLETE | UHCI_INTR_SHORT_PACKET); 179 161 180 162 /* Start the hc with large(64B) packet FSBR */ 181 163 pio_write_16(&instance->registers->usbcmd, 182 164 UHCI_CMD_RUN_STOP | UHCI_CMD_MAX_PACKET | UHCI_CMD_CONFIGURE); 165 usb_log_debug("Started UHCI HC.\n"); 183 166 } 184 167 /*----------------------------------------------------------------------------*/ … … 186 169 { 187 170 assert(instance); 188 #define CHECK_RET_DEST_CMDS_RETURN(ret, message...) \189 if (ret != EOK) { \190 usb_log_error(message); \191 if (instance->interrupt_code.cmds != NULL) \192 free(instance->interrupt_code.cmds); \193 return ret; \194 } else (void) 0195 171 196 172 /* init interrupt code */ 197 instance->interrupt_code.cmds = malloc(sizeof(uhci_cmds)); 198 int ret = (instance->interrupt_code.cmds == NULL) ? ENOMEM : EOK; 199 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to allocate interrupt cmds space.\n"); 200 201 { 202 irq_cmd_t *interrupt_commands = instance->interrupt_code.cmds; 203 memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds)); 204 interrupt_commands[0].addr = (void*)&instance->registers->usbsts; 205 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 206 instance->interrupt_code.cmdcount = 207 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 208 } 173 irq_cmd_t *interrupt_commands = malloc(sizeof(uhci_cmds)); 174 if (interrupt_commands == NULL) { 175 return ENOMEM; 176 } 177 memcpy(interrupt_commands, uhci_cmds, sizeof(uhci_cmds)); 178 interrupt_commands[0].addr = (void*)&instance->registers->usbsts; 179 interrupt_commands[1].addr = (void*)&instance->registers->usbsts; 180 instance->interrupt_code.cmds = interrupt_commands; 181 instance->interrupt_code.cmdcount = 182 sizeof(uhci_cmds) / sizeof(irq_cmd_t); 209 183 210 184 /* init transfer lists */ 211 ret = uhci_init_transfer_lists(instance);212 CHECK_RET_ DEST_CMDS_RETURN(ret, "Failed to initialize transfer lists.\n");185 int ret = uhci_init_transfer_lists(instance); 186 CHECK_RET_RETURN(ret, "Failed to initialize transfer lists.\n"); 213 187 usb_log_debug("Initialized transfer lists.\n"); 214 188 … … 216 190 instance->frame_list = get_page(); 217 191 ret = instance ? EOK : ENOMEM; 218 CHECK_RET_ DEST_CMDS_RETURN(ret, "Failed to get frame list page.\n");192 CHECK_RET_RETURN(ret, "Failed to get frame list page.\n"); 219 193 usb_log_debug("Initialized frame list.\n"); 220 194 … … 223 197 instance->transfers_interrupt.queue_head_pa 224 198 | LINK_POINTER_QUEUE_HEAD_FLAG; 225 226 199 unsigned i = 0; 227 200 for(; i < UHCI_FRAME_LIST_COUNT; ++i) { … … 230 203 231 204 /* init address keeper(libusb) */ 232 device_keeper_init(&instance->device_manager); 233 usb_log_debug("Initialized device manager.\n"); 234 235 return EOK; 236 #undef CHECK_RET_DEST_CMDS_RETURN 205 usb_address_keeping_init(&instance->address_manager, USB11_ADDRESS_MAX); 206 usb_log_debug("Initialized address manager.\n"); 207 208 return EOK; 237 209 } 238 210 /*----------------------------------------------------------------------------*/ … … 240 212 { 241 213 assert(instance); 242 #define CHECK_RET_CLEAR_RETURN(ret, message...) \243 if (ret != EOK) { \244 usb_log_error(message); \245 transfer_list_fini(&instance->transfers_bulk_full); \246 transfer_list_fini(&instance->transfers_control_full); \247 transfer_list_fini(&instance->transfers_control_slow); \248 transfer_list_fini(&instance->transfers_interrupt); \249 return ret; \250 } else (void) 0251 214 252 215 /* initialize TODO: check errors */ 253 216 int ret; 254 217 ret = transfer_list_init(&instance->transfers_bulk_full, "BULK_FULL"); 255 CHECK_RET_CLEAR_RETURN(ret, "Failed to init BULK list."); 256 218 assert(ret == EOK); 257 219 ret = transfer_list_init(&instance->transfers_control_full, "CONTROL_FULL"); 258 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL FULL list."); 259 220 assert(ret == EOK); 260 221 ret = transfer_list_init(&instance->transfers_control_slow, "CONTROL_SLOW"); 261 CHECK_RET_CLEAR_RETURN(ret, "Failed to init CONTROL SLOW list."); 262 222 assert(ret == EOK); 263 223 ret = transfer_list_init(&instance->transfers_interrupt, "INTERRUPT"); 264 CHECK_RET_CLEAR_RETURN(ret, "Failed to init INTERRUPT list.");224 assert(ret == EOK); 265 225 266 226 transfer_list_set_next(&instance->transfers_control_full, … … 289 249 290 250 return EOK; 291 #undef CHECK_RET_CLEAR_RETURN292 251 } 293 252 /*----------------------------------------------------------------------------*/ … … 296 255 assert(instance); 297 256 assert(batch); 298 const int low_speed = (batch->speed == USB_SPEED_LOW);257 const int low_speed = (batch->speed == LOW_SPEED); 299 258 if (!allowed_usb_packet( 300 259 low_speed, batch->transfer_type, batch->max_packet_size)) { 301 260 usb_log_warning("Invalid USB packet specified %s SPEED %d %zu.\n", 302 261 low_speed ? "LOW" : "FULL" , batch->transfer_type, 303 262 batch->max_packet_size); 304 263 return ENOTSUP; … … 317 276 { 318 277 assert(instance); 319 transfer_list_remove_finished(&instance->transfers_interrupt); 320 transfer_list_remove_finished(&instance->transfers_control_slow); 321 transfer_list_remove_finished(&instance->transfers_control_full); 322 transfer_list_remove_finished(&instance->transfers_bulk_full); 278 if ((status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) == 0) 279 return; 280 usb_log_debug("UHCI interrupt: %X.\n", status); 281 transfer_list_check(&instance->transfers_interrupt); 282 transfer_list_check(&instance->transfers_control_slow); 283 transfer_list_check(&instance->transfers_control_full); 284 transfer_list_check(&instance->transfers_bulk_full); 323 285 } 324 286 /*----------------------------------------------------------------------------*/ … … 329 291 assert(instance); 330 292 331 while 293 while(1) { 332 294 uint16_t status = pio_read_16(&instance->registers->usbsts); 333 if (status != 0)334 usb_log_debug2("UHCI status: %x.\n", status);335 status |= 1;336 295 uhci_interrupt(instance, status); 337 pio_write_16(&instance->registers->usbsts, 0x1f); 338 async_usleep(UHCI_CLEANER_TIMEOUT * 5); 296 async_usleep(UHCI_CLEANER_TIMEOUT); 339 297 } 340 298 return EOK; … … 345 303 uhci_t *instance = (uhci_t*)arg; 346 304 assert(instance); 347 348 #define QH(queue) \349 instance->transfers_##queue.queue_head350 351 305 while (1) { 352 306 const uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 353 307 const uint16_t sts = pio_read_16(&instance->registers->usbsts); 354 const uint16_t intr = 355 pio_read_16(&instance->registers->usbintr); 356 357 if (((cmd & UHCI_CMD_RUN_STOP) != 1) || (sts != 0)) { 358 usb_log_debug2("Command: %X Status: %X Intr: %x\n", 359 cmd, sts, intr); 360 } 361 362 uintptr_t frame_list = 363 pio_read_32(&instance->registers->flbaseadd) & ~0xfff; 308 const uint16_t intr = pio_read_16(&instance->registers->usbintr); 309 usb_log_debug("Command: %X Status: %X Interrupts: %x\n", 310 cmd, sts, intr); 311 312 uintptr_t frame_list = pio_read_32(&instance->registers->flbaseadd); 364 313 if (frame_list != addr_to_phys(instance->frame_list)) { 365 314 usb_log_debug("Framelist address: %p vs. %p.\n", 366 frame_list, addr_to_phys(instance->frame_list)); 367 } 368 315 frame_list, addr_to_phys(instance->frame_list)); 316 } 369 317 int frnum = pio_read_16(&instance->registers->frnum) & 0x3ff; 370 318 usb_log_debug2("Framelist item: %d \n", frnum ); 371 319 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) {320 queue_head_t* qh = instance->transfers_interrupt.queue_head; 321 322 if ((instance->frame_list[frnum] & (~0xf)) != (uintptr_t)addr_to_phys(qh)) { 375 323 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 } 324 instance->frame_list[frnum] & (~0xf), addr_to_phys(qh)); 325 } 326 327 if ((qh->next_queue & (~0xf)) 328 != (uintptr_t)addr_to_phys(instance->transfers_control_slow.queue_head)) { 329 usb_log_debug("Control Slow QH: %p vs. %p.\n", qh->next_queue & (~0xf), 330 addr_to_phys(instance->transfers_control_slow.queue_head)); 331 } 332 qh = instance->transfers_control_slow.queue_head; 333 334 if ((qh->next_queue & (~0xf)) 335 != (uintptr_t)addr_to_phys(instance->transfers_control_full.queue_head)) { 336 usb_log_debug("Control Full QH: %p vs. %p.\n", qh->next_queue & (~0xf), 337 addr_to_phys(instance->transfers_control_full.queue_head));\ 338 } 339 qh = instance->transfers_control_full.queue_head; 340 341 if ((qh->next_queue & (~0xf)) 342 != (uintptr_t)addr_to_phys(instance->transfers_bulk_full.queue_head)) { 343 usb_log_debug("Bulk QH: %p vs. %p.\n", qh->next_queue & (~0xf), 344 addr_to_phys(instance->transfers_bulk_full.queue_head)); 345 } 346 /* 347 uint16_t cmd = pio_read_16(&instance->registers->usbcmd); 348 cmd |= UHCI_CMD_RUN_STOP; 349 pio_write_16(&instance->registers->usbcmd, cmd); 350 */ 399 351 async_usleep(UHCI_DEBUGER_TIMEOUT); 400 352 } 401 353 return 0; 402 #undef QH403 354 } 404 355 /*----------------------------------------------------------------------------*/ 405 356 bool allowed_usb_packet( 406 357 bool low_speed, usb_transfer_type_t transfer, size_t size) 407 358 { 408 359 /* 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); 360 switch(transfer) { 361 case USB_TRANSFER_ISOCHRONOUS: 362 return (!low_speed && size < 1024); 363 case USB_TRANSFER_INTERRUPT: 364 return size <= (low_speed ? 8 : 64); 365 case USB_TRANSFER_CONTROL: /* device specifies its own max size */ 366 return (size <= (low_speed ? 8 : 64)); 367 case USB_TRANSFER_BULK: /* device specifies its own max size */ 368 return (!low_speed && size <= 64); 419 369 } 420 370 return false; -
uspace/drv/uhci-hcd/uhci.h
r8c877b2 rdff940f8 41 41 #include <ddi.h> 42 42 43 #include <usb/addrkeep.h> 43 44 #include <usbhc_iface.h> 44 45 46 #include "transfer_list.h" 45 47 #include "batch.h" 46 #include "transfer_list.h"47 #include "utils/device_keeper.h"48 48 49 49 typedef struct uhci_regs { … … 82 82 83 83 typedef struct uhci { 84 device_keeper_t device_manager; 85 84 usb_address_keeping_t address_manager; 86 85 volatile regs_t *registers; 87 86 -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.c
r8c877b2 rdff940f8 39 39 40 40 void transfer_descriptor_init(transfer_descriptor_t *instance, 41 int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,41 int error_count, size_t size, bool toggle, bool isochronous, 42 42 usb_target_t target, int pid, void *buffer, transfer_descriptor_t *next) 43 43 { … … 50 50 instance->status = 0 51 51 | ((error_count & TD_STATUS_ERROR_COUNT_MASK) << TD_STATUS_ERROR_COUNT_POS) 52 | (low_speed ? TD_STATUS_LOW_SPEED_FLAG : 0)53 52 | TD_STATUS_ERROR_ACTIVE; 54 53 … … 67 66 } 68 67 69 usb_log_ debug2("Created TD: %X:%X:%X:%X(%p).\n",68 usb_log_info("Created TD: %X:%X:%X:%X(%p).\n", 70 69 instance->next, instance->status, instance->device, 71 70 instance->buffer_ptr, buffer); 71 #if 0 72 if (size) { 73 unsigned char * buff = buffer; 74 uhci_print_verbose("TD Buffer dump(%p-%dB): ", buffer, size); 75 unsigned i = 0; 76 /* TODO: Verbose? */ 77 for (; i < size; ++i) { 78 printf((i & 1) ? "%x " : "%x", buff[i]); 79 } 80 printf("\n"); 81 } 82 #endif 72 83 } 73 84 /*----------------------------------------------------------------------------*/ … … 77 88 78 89 if ((instance->status & TD_STATUS_ERROR_STALLED) != 0) 79 return E STALL;90 return EIO; 80 91 81 92 if ((instance->status & TD_STATUS_ERROR_CRC) != 0) 82 return E BADCHECKSUM;93 return EAGAIN; 83 94 84 95 if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0) -
uspace/drv/uhci-hcd/uhci_struct/transfer_descriptor.h
r8c877b2 rdff940f8 92 92 93 93 void transfer_descriptor_init(transfer_descriptor_t *instance, 94 int error_count, size_t size, bool toggle, bool isochronous, bool low_speed,94 int error_count, size_t size, bool toggle, bool isochronous, 95 95 usb_target_t target, int pid, void *buffer, transfer_descriptor_t * next); 96 96 -
uspace/drv/uhci-rhd/main.c
r8c877b2 rdff940f8 33 33 */ 34 34 #include <ddf/driver.h> 35 #include <devman.h>36 #include <device/hw_res.h>37 35 #include <usb_iface.h> 38 36 #include <usb/ddfiface.h> … … 45 43 46 44 #define NAME "uhci-rhd" 47 static int hc_get_my_registers(ddf_dev_t *dev,48 uintptr_t *io_reg_address, size_t *io_reg_size);49 45 50 46 static int usb_iface_get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle) … … 84 80 } 85 81 86 uintptr_t io_regs = 0; 87 size_t io_size = 0; 88 89 int ret = hc_get_my_registers(device, &io_regs, &io_size); 90 assert(ret == EOK); 91 92 /* TODO: verify values from hc */ 93 usb_log_info("I/O regs at 0x%X (size %zu).\n", io_regs, io_size); 94 ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device); 82 /* TODO: get register values from hc */ 83 int ret = uhci_root_hub_init(rh, (void*)0xc030, 4, device); 95 84 if (ret != EOK) { 96 85 usb_log_error("Failed(%d) to initialize driver instance.\n", ret); … … 113 102 .driver_ops = &uhci_rh_driver_ops 114 103 }; 115 /*----------------------------------------------------------------------------*/ 104 116 105 int main(int argc, char *argv[]) 117 106 { 118 usb_log_enable(USB_LOG_LEVEL_ DEBUG, NAME);107 usb_log_enable(USB_LOG_LEVEL_INFO, NAME); 119 108 return ddf_driver_main(&uhci_rh_driver); 120 }121 /*----------------------------------------------------------------------------*/122 int hc_get_my_registers(ddf_dev_t *dev,123 uintptr_t *io_reg_address, size_t *io_reg_size)124 {125 assert(dev != NULL);126 127 int parent_phone = devman_parent_device_connect(dev->handle,128 IPC_FLAG_BLOCKING);129 if (parent_phone < 0) {130 return parent_phone;131 }132 133 int rc;134 135 hw_resource_list_t hw_resources;136 rc = hw_res_get_resource_list(parent_phone, &hw_resources);137 if (rc != EOK) {138 goto leave;139 }140 141 uintptr_t io_address = 0;142 size_t io_size = 0;143 bool io_found = false;144 145 size_t i;146 for (i = 0; i < hw_resources.count; i++) {147 hw_resource_t *res = &hw_resources.resources[i];148 switch (res->type) {149 case IO_RANGE:150 io_address = (uintptr_t)151 res->res.io_range.address;152 io_size = res->res.io_range.size;153 io_found = true;154 break;155 default:156 break;157 }158 }159 160 if (!io_found) {161 rc = ENOENT;162 goto leave;163 }164 165 if (io_reg_address != NULL) {166 *io_reg_address = io_address;167 }168 if (io_reg_size != NULL) {169 *io_reg_size = io_size;170 }171 rc = EOK;172 leave:173 async_hangup(parent_phone);174 175 return rc;176 109 } 177 110 /** -
uspace/drv/uhci-rhd/port.c
r8c877b2 rdff940f8 34 34 #include <errno.h> 35 35 #include <str_error.h> 36 #include <fibril_synch.h>37 36 38 37 #include <usb/usb.h> /* usb_address_t */ … … 46 45 #include "port_status.h" 47 46 48 static int uhci_port_new_device(uhci_port_t *port , uint16_t status);47 static int uhci_port_new_device(uhci_port_t *port); 49 48 static int uhci_port_remove_device(uhci_port_t *port); 50 49 static int uhci_port_set_enabled(uhci_port_t *port, bool enabled); 51 50 static int uhci_port_check(void *port); 52 static int new_device_enable_port(int portno, void *arg);53 51 54 52 int uhci_port_init( 55 53 uhci_port_t *port, port_status_t *address, unsigned number, 56 unsigned usec, ddf_dev_t *rh )54 unsigned usec, ddf_dev_t *rh, int parent_phone) 57 55 { 58 56 assert(port); … … 71 69 port->checker = fibril_create(uhci_port_check, port); 72 70 if (port->checker == 0) { 73 usb_log_error("Port(%p - %d): failed to launch root hub fibril.", 74 port->address, port->number); 71 usb_log_error(": failed to launch root hub fibril."); 75 72 return ENOMEM; 76 73 } 77 74 fibril_add_ready(port->checker); 78 usb_log_debug( "Port(%p - %d): Added fibril. %x\n",79 port->address, port->number, port->checker);75 usb_log_debug( 76 "Added fibril for port %d: %p.\n", number, port->checker); 80 77 return EOK; 81 78 } … … 93 90 uhci_port_t *port_instance = port; 94 91 assert(port_instance); 95 // port_status_write(port_instance->address, 0);96 97 unsigned count = 0;98 92 99 93 while (1) { 100 async_usleep(port_instance->wait_period_usec);101 102 94 /* read register value */ 103 95 port_status_t port_status = … … 105 97 106 98 /* debug print */ 107 static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx); 108 fibril_mutex_lock(&dbg_mtx); 109 usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n", 110 port_instance->address, port_instance->number, port_status, count++); 111 // print_port_status(port_status); 112 fibril_mutex_unlock(&dbg_mtx); 113 114 if ((port_status & STATUS_CONNECTED_CHANGED) != 0) { 115 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n", 116 port_instance->address, port_instance->number, port_status); 117 118 99 usb_log_debug("Port %d status at %p: 0x%04x.\n", 100 port_instance->number, port_instance->address, port_status); 101 print_port_status(port_status); 102 103 if (port_status & STATUS_CONNECTED_CHANGED) { 119 104 int rc = usb_hc_connection_open( 120 105 &port_instance->hc_connection); 121 106 if (rc != EOK) { 122 usb_log_error("Port(%p - %d): Failed to connect to HC.", 123 port_instance->address, port_instance->number); 124 continue; 107 usb_log_error("Failed to connect to HC."); 108 goto next; 125 109 } 126 110 127 /* remove any old device */128 if (port_instance->attached_device) {129 u sb_log_debug("Port(%p - %d): Removing device.\n",130 port_instance->address, port_instance->number);111 if (port_status & STATUS_CONNECTED) { 112 /* new device */ 113 uhci_port_new_device(port_instance); 114 } else { 131 115 uhci_port_remove_device(port_instance); 132 }133 134 if ((port_status & STATUS_CONNECTED) != 0) {135 /* new device */136 uhci_port_new_device(port_instance, port_status);137 } else {138 /* ack changes by writing one to WC bits */139 port_status_write(port_instance->address, port_status);140 usb_log_debug("Port(%p - %d): Change status ACK.\n",141 port_instance->address, port_instance->number);142 116 } 143 117 … … 145 119 &port_instance->hc_connection); 146 120 if (rc != EOK) { 147 usb_log_error(" Port(%p - %d): Failed to disconnect from HC.",148 port_instance->address, port_instance->number);121 usb_log_error("Failed to disconnect from HC."); 122 goto next; 149 123 } 150 124 } 125 next: 126 async_usleep(port_instance->wait_period_usec); 151 127 } 152 128 return EOK; … … 163 139 uhci_port_t *port = (uhci_port_t *) arg; 164 140 165 usb_log_debug2("Port(%p - %d): new_device_enable_port.\n", 166 port->address, port->number); 141 usb_log_debug("new_device_enable_port(%d)\n", port->number); 167 142 168 143 /* … … 172 147 async_usleep(100000); 173 148 149 /* Enable the port. */ 150 uhci_port_set_enabled(port, true); 174 151 175 152 /* The hub maintains the reset signal to that port for 10 ms … … 177 154 */ 178 155 { 179 usb_log_debug(" Port(%p - %d): Reset Signal start.\n",180 port-> address, port->number);156 usb_log_debug("Reset Signal start on port %d.\n", 157 port->number); 181 158 port_status_t port_status = 182 159 port_status_read(port->address); … … 188 165 port_status &= ~STATUS_IN_RESET; 189 166 port_status_write(port->address, port_status); 190 usb_log_debug("Port(%p - %d): Reset Signal stop.\n", 191 port->address, port->number); 192 } 193 194 /* Enable the port. */ 195 uhci_port_set_enabled(port, true); 196 197 return EOK; 198 } 199 200 /*----------------------------------------------------------------------------*/ 201 static int uhci_port_new_device(uhci_port_t *port, uint16_t status) 167 usb_log_debug("Reset Signal stop on port %d.\n", 168 port->number); 169 } 170 171 return EOK; 172 } 173 174 /*----------------------------------------------------------------------------*/ 175 static int uhci_port_new_device(uhci_port_t *port) 202 176 { 203 177 assert(port); 204 178 assert(usb_hc_connection_is_opened(&port->hc_connection)); 205 179 206 usb_log_info("Port(%p-%d): Detected new device.\n", 207 port->address, port->number); 180 usb_log_info("Detected new device on port %u.\n", port->number); 208 181 209 182 usb_address_t dev_addr; 210 183 int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection, 211 ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW :USB_SPEED_FULL,184 USB_SPEED_FULL, 212 185 new_device_enable_port, port->number, port, 213 186 &dev_addr, &port->attached_device, NULL, NULL, NULL); 214 215 187 if (rc != EOK) { 216 usb_log_error(" Port(%p-%d): Failed(%d) adding new device: %s.\n",217 port-> address, port->number, rc, str_error(rc));188 usb_log_error("Failed adding new device on port %u: %s.\n", 189 port->number, str_error(rc)); 218 190 uhci_port_set_enabled(port, false); 219 191 return rc; 220 192 } 221 193 222 usb_log_info(" Port(%p-%d): New devicehas address %d (handle %zu).\n",223 port-> address, port->number, dev_addr, port->attached_device);194 usb_log_info("New device on port %u has address %d (handle %zu).\n", 195 port->number, dev_addr, port->attached_device); 224 196 225 197 return EOK; … … 229 201 static int uhci_port_remove_device(uhci_port_t *port) 230 202 { 231 usb_log_error(" Port(%p-%d):Don't know how to remove device %#x.\n",232 port->address, port->number,(unsigned int)port->attached_device);203 usb_log_error("Don't know how to remove device %#x.\n", 204 (unsigned int)port->attached_device); 233 205 // uhci_port_set_enabled(port, false); 234 206 return EOK; … … 251 223 port_status_write(port->address, port_status); 252 224 253 usb_log_info(" Port(%p-%d): %sabled port.\n",254 port->address, port->number, enabled ? "En" : "Dis");225 usb_log_info("%s port %d.\n", 226 enabled ? "Enabled" : "Disabled", port->number); 255 227 return EOK; 256 228 } -
uspace/drv/uhci-rhd/port.h
r8c877b2 rdff940f8 55 55 int uhci_port_init( 56 56 uhci_port_t *port, port_status_t *address, unsigned number, 57 unsigned usec, ddf_dev_t *rh );57 unsigned usec, ddf_dev_t *rh, int parent_phone); 58 58 59 59 void uhci_port_fini(uhci_port_t *port); -
uspace/drv/uhci-rhd/port_status.c
r8c877b2 rdff940f8 41 41 struct flag_name 42 42 { 43 u int16_tflag;43 unsigned flag; 44 44 const char *name; 45 45 }; … … 65 65 for (;i < sizeof(flags)/sizeof(struct flag_name); ++i) { 66 66 usb_log_debug2("\t%s status: %s.\n", flags[i].name, 67 ((value & flags[i].flag) != 0)? "YES" : "NO");67 value & flags[i].flag ? "YES" : "NO"); 68 68 } 69 69 } -
uspace/drv/uhci-rhd/port_status.h
r8c877b2 rdff940f8 41 41 typedef uint16_t port_status_t; 42 42 43 #define STATUS_CONNECTED (1 << 0) 44 #define STATUS_CONNECTED_CHANGED (1 << 1) 45 #define STATUS_ENABLED (1 << 2) 46 #define STATUS_ENABLED_CHANGED (1 << 3) 47 #define STATUS_LINE_D_PLUS (1 << 4) 48 #define STATUS_LINE_D_MINUS (1 << 5) 49 #define STATUS_RESUME (1 << 6) 50 #define STATUS_ALWAYS_ONE (1 << 7) 43 enum { 44 STATUS_CONNECTED = 1 << 0, 45 STATUS_CONNECTED_CHANGED = 1 << 1, 46 STATUS_ENABLED = 1 << 2, 47 STATUS_ENABLED_CHANGED = 1 << 3, 48 STATUS_LINE_D_PLUS = 1 << 4, 49 STATUS_LINE_D_MINUS = 1 << 5, 50 STATUS_RESUME = 1 << 6, 51 STATUS_ALWAYS_ONE = 1 << 7, 51 52 52 #define STATUS_LOW_SPEED (1 << 8) 53 #define STATUS_IN_RESET (1 << 9) 54 #define STATUS_SUSPEND (1 << 12) 53 STATUS_LOW_SPEED = 1 << 8, 54 STATUS_IN_RESET = 1 << 9, 55 STATUS_SUSPEND = 1 << 12, 56 }; 55 57 56 58 static inline port_status_t port_status_read(port_status_t * address) -
uspace/drv/uhci-rhd/root_hub.c
r8c877b2 rdff940f8 40 40 #include "root_hub.h" 41 41 42 42 43 int uhci_root_hub_init( 43 44 uhci_root_hub_t *instance, void *addr, size_t size, ddf_dev_t *rh) … … 46 47 assert(rh); 47 48 int ret; 49 ret = usb_hc_find(rh->handle, &instance->hc_handle); 50 usb_log_info("rh found(%d) hc handle: %d.\n", ret, instance->hc_handle); 51 if (ret != EOK) { 52 return ret; 53 } 48 54 49 55 /* allow access to root hub registers */ 50 56 assert(sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT == size); 51 57 port_status_t *regs; 52 ret = pio_enable(addr, size, (void**)®s); 58 ret = pio_enable( 59 addr, sizeof(port_status_t) * UHCI_ROOT_HUB_PORT_COUNT, (void**)®s); 53 60 54 61 if (ret < 0) { … … 60 67 unsigned i = 0; 61 68 for (; i < UHCI_ROOT_HUB_PORT_COUNT; ++i) { 69 /* connect to the parent device (HC) */ 70 int parent_phone = devman_device_connect(instance->hc_handle, 0); 71 //usb_drv_hc_connect(rh, instance->hc_handle, 0); 72 if (parent_phone < 0) { 73 usb_log_error("Failed to connect to the HC device port %d.\n", i); 74 return parent_phone; 75 } 62 76 /* mind pointer arithmetics */ 63 ret = uhci_port_init(64 &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh );77 int ret = uhci_port_init( 78 &instance->ports[i], regs + i, i, ROOT_HUB_WAIT_USEC, rh, parent_phone); 65 79 if (ret != EOK) { 66 80 unsigned j = 0; -
uspace/drv/uhci-rhd/root_hub.h
r8c877b2 rdff940f8 41 41 42 42 #define UHCI_ROOT_HUB_PORT_COUNT 2 43 #define ROOT_HUB_WAIT_USEC 5000000 /* 5 seconds */ 43 #define UHCI_ROOT_HUB_PORT_REGISTERS_OFFSET 0x10 44 #define ROOT_HUB_WAIT_USEC 10000000 /* 10 seconds */ 44 45 45 46 typedef struct root_hub { -
uspace/drv/usbhid/Makefile
r8c877b2 rdff940f8 39 39 SOURCES = \ 40 40 main.c \ 41 descparser.c \ 42 descdump.c \ 41 43 conv.c \ 42 hidreq.c \43 kbddev.c \44 hiddev.c \45 44 $(STOLEN_LAYOUT_SOURCES) 46 45 -
uspace/drv/usbhid/conv.c
r8c877b2 rdff940f8 36 36 #include <io/keycode.h> 37 37 #include <stdint.h> 38 #include <stdio.h>39 #include <usb/debug.h>40 38 #include "conv.h" 41 39 … … 143 141 //[0xe7] = KC_R // TODO: right GUI 144 142 145 [0x53] = KC_NUM_LOCK,146 [0x54] = KC_NSLASH,147 [0x55] = KC_NTIMES,148 [0x56] = KC_NMINUS,149 [0x57] = KC_NPLUS,150 [0x58] = KC_NENTER,151 [0x59] = KC_N1,152 [0x5a] = KC_N2,153 [0x5b] = KC_N3,154 [0x5c] = KC_N4,155 [0x5d] = KC_N5,156 [0x5e] = KC_N6,157 [0x5f] = KC_N7,158 [0x60] = KC_N8,159 [0x61] = KC_N9,160 [0x62] = KC_N0,161 [0x63] = KC_NPERIOD162 163 143 }; 164 144 165 unsigned int usb hid_parse_scancode(int scancode)145 unsigned int usbkbd_parse_scancode(int scancode) 166 146 { 147 // console_ev_type_t type; 167 148 unsigned int key; 168 149 int *map = scanmap_simple; 169 150 size_t map_length = sizeof(scanmap_simple) / sizeof(int); 151 152 /* 153 * ACK/NAK are returned as response to us sending a command. 154 * We are not interested in them. 155 */ 156 // if (scancode == SC_ACK || scancode == SC_NAK) 157 // return; 158 159 // if (scancode == 0xe0) { 160 // ds = ds_e; 161 // return; 162 // } 163 164 // switch (ds) { 165 // case ds_s: 166 // map = scanmap_simple; 167 // map_length = sizeof(scanmap_simple) / sizeof(int); 168 // break; 169 // case ds_e: 170 // map = scanmap_e0; 171 // map_length = sizeof(scanmap_e0) / sizeof(int); 172 // break; 173 // default: 174 // map = NULL; 175 // map_length = 0; 176 // } 177 178 // ds = ds_s; 179 180 // if (scancode & 0x80) { 181 // scancode &= ~0x80; 182 // type = KEY_RELEASE; 183 // } else { 184 // type = KEY_PRESS; 185 // } 170 186 171 187 if ((scancode < 0) || ((size_t) scancode >= map_length)) … … 173 189 174 190 key = map[scancode]; 175 191 // if (key != 0) 192 // kbd_push_ev(type, key); 176 193 return key; 177 194 } -
uspace/drv/usbhid/conv.h
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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 "hid.h" 54 #include "descparser.h" 55 #include "descdump.h" 56 #include "conv.h" 57 #include "layout.h" 58 59 #define BUFFER_SIZE 8 46 60 #define NAME "usbhid" 47 61 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"); 62 #define GUESSED_POLL_ENDPOINT 1 63 64 /** Keyboard polling endpoint description for boot protocol class. */ 65 static usb_endpoint_description_t poll_endpoint_description = { 66 .transfer_type = USB_TRANSFER_INTERRUPT, 67 .direction = USB_DIRECTION_IN, 68 .interface_class = USB_CLASS_HID, 69 .interface_subclass = USB_HID_SUBCLASS_BOOT, 70 .interface_protocol = USB_HID_PROTOCOL_KEYBOARD, 71 .flags = 0 72 }; 73 74 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 75 static ddf_dev_ops_t keyboard_ops = { 76 .default_handler = default_connection_handler 77 }; 78 79 static int console_callback_phone = -1; 80 81 /** Default handler for IPC methods not handled by DDF. 82 * 83 * @param dev Device handling the call. 84 * @param icallid Call id. 85 * @param icall Call data. 86 */ 87 void default_connection_handler(ddf_fun_t *fun, 88 ipc_callid_t icallid, ipc_call_t *icall) 89 { 90 sysarg_t method = IPC_GET_IMETHOD(*icall); 91 92 if (method == IPC_M_CONNECT_TO_ME) { 93 int callback = IPC_GET_ARG5(*icall); 94 95 if (console_callback_phone != -1) { 96 async_answer_0(icallid, ELIMIT); 97 return; 98 } 99 100 console_callback_phone = callback; 101 async_answer_0(icallid, EOK); 102 return; 103 } 104 105 async_answer_0(icallid, EINVAL); 106 } 107 108 #if 0 109 static void send_key(int key, int type, wchar_t c) { 110 async_msg_4(console_callback_phone, KBD_EVENT, type, key, 111 KM_NUM_LOCK, c); 112 } 113 #endif 114 115 /* 116 * TODO: Move somewhere else 117 */ 118 /* 119 #define BYTES_PER_LINE 12 120 121 static void dump_buffer(const char *msg, const uint8_t *buffer, size_t length) 122 { 123 printf("%s\n", msg); 124 125 size_t i; 126 for (i = 0; i < length; i++) { 127 printf(" 0x%02X", buffer[i]); 128 if (((i > 0) && (((i+1) % BYTES_PER_LINE) == 0)) 129 || (i + 1 == length)) { 130 printf("\n"); 131 } 132 } 133 } 134 */ 135 /* 136 * Copy-paste from srv/hid/kbd/generic/kbd.c 137 */ 138 139 /** Currently active modifiers. 140 * 141 * TODO: put to device? 142 */ 143 static unsigned mods = KM_NUM_LOCK; 144 145 /** Currently pressed lock keys. We track these to tackle autorepeat. 146 * 147 * TODO: put to device? 148 */ 149 static unsigned lock_keys; 150 151 #define NUM_LAYOUTS 3 152 153 static layout_op_t *layout[NUM_LAYOUTS] = { 154 &us_qwerty_op, 155 &us_dvorak_op, 156 &cz_op 157 }; 158 159 static int active_layout = 0; 160 161 static void kbd_push_ev(int type, unsigned int key) 162 { 163 console_event_t ev; 164 unsigned mod_mask; 165 166 // TODO: replace by our own parsing?? or are the key codes identical?? 167 switch (key) { 168 case KC_LCTRL: mod_mask = KM_LCTRL; break; 169 case KC_RCTRL: mod_mask = KM_RCTRL; break; 170 case KC_LSHIFT: mod_mask = KM_LSHIFT; break; 171 case KC_RSHIFT: mod_mask = KM_RSHIFT; break; 172 case KC_LALT: mod_mask = KM_LALT; break; 173 case KC_RALT: mod_mask = KM_RALT; break; 174 default: mod_mask = 0; break; 175 } 176 177 if (mod_mask != 0) { 178 if (type == KEY_PRESS) 179 mods = mods | mod_mask; 180 else 181 mods = mods & ~mod_mask; 182 } 183 184 switch (key) { 185 case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; 186 case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break; 187 case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break; 188 default: mod_mask = 0; break; 189 } 190 191 if (mod_mask != 0) { 192 if (type == KEY_PRESS) { 193 /* 194 * Only change lock state on transition from released 195 * to pressed. This prevents autorepeat from messing 196 * up the lock state. 197 */ 198 mods = mods ^ (mod_mask & ~lock_keys); 199 lock_keys = lock_keys | mod_mask; 200 201 /* Update keyboard lock indicator lights. */ 202 // TODO 203 //kbd_ctl_set_ind(mods); 204 } else { 205 lock_keys = lock_keys & ~mod_mask; 206 } 207 } 208 /* 209 printf("type: %d\n", type); 210 printf("mods: 0x%x\n", mods); 211 printf("keycode: %u\n", key); 212 */ 213 214 if (type == KEY_PRESS && (mods & KM_LCTRL) && 215 key == KC_F1) { 216 active_layout = 0; 217 layout[active_layout]->reset(); 218 return; 219 } 220 221 if (type == KEY_PRESS && (mods & KM_LCTRL) && 222 key == KC_F2) { 223 active_layout = 1; 224 layout[active_layout]->reset(); 225 return; 226 } 227 228 if (type == KEY_PRESS && (mods & KM_LCTRL) && 229 key == KC_F3) { 230 active_layout = 2; 231 layout[active_layout]->reset(); 232 return; 233 } 234 235 ev.type = type; 236 ev.key = key; 237 ev.mods = mods; 238 239 ev.c = layout[active_layout]->parse_ev(&ev); 240 241 printf("Sending key %d to the console\n", ev.key); 242 assert(console_callback_phone != -1); 243 async_msg_4(console_callback_phone, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c); 244 } 245 /* 246 * End of copy-paste 247 */ 248 249 /* 250 * TODO: 251 * 1) key press / key release - how does the keyboard notify about release? 252 * 2) layouts (use the already defined), not important now 253 * 3) 254 */ 255 256 /* 257 * Callbacks for parser 258 */ 259 static void usbkbd_process_keycodes(const uint8_t *key_codes, size_t count, 260 uint8_t modifiers, void *arg) 261 { 262 printf("Got keys: "); 263 unsigned i; 264 for (i = 0; i < count; ++i) { 265 printf("%d ", key_codes[i]); 266 } 267 printf("\n"); 268 269 for (i = 0; i < count; ++i) { 270 // TODO: Key press / release 271 272 // TODO: NOT WORKING 273 unsigned int key = usbkbd_parse_scancode(key_codes[i]); 274 275 if (key == 0) { 276 continue; 277 } 278 kbd_push_ev(KEY_PRESS, key); 279 } 280 printf("\n"); 281 } 282 283 /* 284 * Kbd functions 285 */ 286 static int usbkbd_get_report_descriptor(usb_hid_dev_kbd_t *kbd_dev) 287 { 288 // iterate over all configurations and interfaces 289 // TODO: more configurations!! 290 unsigned i; 291 for (i = 0; i < kbd_dev->conf->config_descriptor.interface_count; ++i) { 292 // TODO: endianness 293 uint16_t length = 294 kbd_dev->conf->interfaces[i].hid_desc.report_desc_info.length; 295 size_t actual_size = 0; 296 297 // allocate space for the report descriptor 298 kbd_dev->conf->interfaces[i].report_desc = (uint8_t *)malloc(length); 299 300 // get the descriptor from the device 301 int rc = usb_request_get_descriptor(&kbd_dev->ctrl_pipe, 302 USB_REQUEST_TYPE_CLASS, USB_DESCTYPE_HID_REPORT, 303 i, 0, 304 kbd_dev->conf->interfaces[i].report_desc, length, 305 &actual_size); 306 307 if (rc != EOK) { 308 return rc; 309 } 310 311 assert(actual_size == length); 312 313 //dump_hid_class_descriptor(0, USB_DESCTYPE_HID_REPORT, 314 // kbd_dev->conf->interfaces[i].report_desc, length); 315 } 316 317 return EOK; 318 } 319 static int usbkbd_process_descriptors(usb_hid_dev_kbd_t *kbd_dev) 320 { 321 // get the first configuration descriptor (TODO: parse also other!) 322 usb_standard_configuration_descriptor_t config_desc; 323 324 int rc; 325 rc = usb_request_get_bare_configuration_descriptor(&kbd_dev->ctrl_pipe, 326 0, &config_desc); 327 328 if (rc != EOK) { 329 return rc; 330 } 331 332 // prepare space for all underlying descriptors 333 uint8_t *descriptors = (uint8_t *)malloc(config_desc.total_length); 334 if (descriptors == NULL) { 335 return ENOMEM; 336 } 337 338 size_t transferred = 0; 339 // get full configuration descriptor 340 rc = usb_request_get_full_configuration_descriptor(&kbd_dev->ctrl_pipe, 341 0, descriptors, 342 config_desc.total_length, &transferred); 343 344 if (rc != EOK) { 345 return rc; 346 } 347 if (transferred != config_desc.total_length) { 348 return ELIMIT; 349 } 350 351 /* 352 * Initialize the interrupt in endpoint. 353 */ 354 usb_endpoint_mapping_t endpoint_mapping[1] = { 355 { 356 .pipe = &kbd_dev->poll_pipe, 357 .description = &poll_endpoint_description, 358 .interface_no = 359 usb_device_get_assigned_interface(kbd_dev->device) 360 } 361 }; 362 rc = usb_endpoint_pipe_initialize_from_configuration( 363 endpoint_mapping, 1, 364 descriptors, config_desc.total_length, 365 &kbd_dev->wire); 366 if (rc != EOK) { 367 usb_log_error("Failed to initialize poll pipe: %s.\n", 368 str_error(rc)); 369 return rc; 370 } 371 if (!endpoint_mapping[0].present) { 372 usb_log_warning("Not accepting device, " \ 373 "not boot-protocol keyboard.\n"); 59 374 return EREFUSED; 60 375 } 61 376 377 378 379 380 kbd_dev->conf = (usb_hid_configuration_t *)calloc(1, 381 sizeof(usb_hid_configuration_t)); 382 if (kbd_dev->conf == NULL) { 383 free(descriptors); 384 return ENOMEM; 385 } 386 387 /*rc = usbkbd_parse_descriptors(descriptors, transferred, kbd_dev->conf); 388 free(descriptors); 389 if (rc != EOK) { 390 printf("Problem with parsing standard descriptors.\n"); 391 return rc; 392 } 393 394 // get and report descriptors*/ 395 rc = usbkbd_get_report_descriptor(kbd_dev); 396 if (rc != EOK) { 397 printf("Problem with parsing HID REPORT descriptor.\n"); 398 return rc; 399 } 400 401 //usbkbd_print_config(kbd_dev->conf); 402 403 /* 404 * TODO: 405 * 1) select one configuration (lets say the first) 406 * 2) how many interfaces?? how to select one?? 407 * ("The default setting for an interface is always alternate setting zero.") 408 * 3) find endpoint which is IN and INTERRUPT (parse), save its number 409 * as the endpoint for polling 410 */ 411 62 412 return EOK; 63 413 } 64 414 65 /*----------------------------------------------------------------------------*/ 415 static usb_hid_dev_kbd_t *usbkbd_init_device(ddf_dev_t *dev) 416 { 417 int rc; 418 419 usb_hid_dev_kbd_t *kbd_dev = (usb_hid_dev_kbd_t *)calloc(1, 420 sizeof(usb_hid_dev_kbd_t)); 421 422 if (kbd_dev == NULL) { 423 fprintf(stderr, NAME ": No memory!\n"); 424 return NULL; 425 } 426 427 kbd_dev->device = dev; 428 429 /* 430 * Initialize the backing connection to the host controller. 431 */ 432 rc = usb_device_connection_initialize_from_device(&kbd_dev->wire, dev); 433 if (rc != EOK) { 434 printf("Problem initializing connection to device: %s.\n", 435 str_error(rc)); 436 goto error_leave; 437 } 438 439 /* 440 * Initialize device pipes. 441 */ 442 rc = usb_endpoint_pipe_initialize_default_control(&kbd_dev->ctrl_pipe, 443 &kbd_dev->wire); 444 if (rc != EOK) { 445 printf("Failed to initialize default control pipe: %s.\n", 446 str_error(rc)); 447 goto error_leave; 448 } 449 450 /* 451 * will need all descriptors: 452 * 1) choose one configuration from configuration descriptors 453 * (set it to the device) 454 * 2) set endpoints from endpoint descriptors 455 */ 456 457 // TODO: get descriptors, parse descriptors and save endpoints 458 usb_endpoint_pipe_start_session(&kbd_dev->ctrl_pipe); 459 //usb_request_set_configuration(&kbd_dev->ctrl_pipe, 1); 460 rc = usbkbd_process_descriptors(kbd_dev); 461 usb_endpoint_pipe_end_session(&kbd_dev->ctrl_pipe); 462 if (rc != EOK) { 463 goto error_leave; 464 } 465 466 return kbd_dev; 467 468 error_leave: 469 free(kbd_dev); 470 return NULL; 471 } 472 473 static void usbkbd_process_interrupt_in(usb_hid_dev_kbd_t *kbd_dev, 474 uint8_t *buffer, size_t actual_size) 475 { 476 usb_hid_report_in_callbacks_t *callbacks = 477 (usb_hid_report_in_callbacks_t *)malloc( 478 sizeof(usb_hid_report_in_callbacks_t)); 479 callbacks->keyboard = usbkbd_process_keycodes; 480 481 //usb_hid_parse_report(kbd_dev->parser, buffer, actual_size, callbacks, 482 // NULL); 483 printf("Calling usb_hid_boot_keyboard_input_report() with size %zu\n", 484 actual_size); 485 //dump_buffer("bufffer: ", buffer, actual_size); 486 int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, callbacks, 487 NULL); 488 if (rc != EOK) { 489 printf("Error in usb_hid_boot_keyboard_input_report(): %d\n", rc); 490 } 491 } 492 493 static void usbkbd_poll_keyboard(usb_hid_dev_kbd_t *kbd_dev) 494 { 495 int rc, sess_rc; 496 uint8_t buffer[BUFFER_SIZE]; 497 size_t actual_size; 498 499 printf("Polling keyboard...\n"); 500 501 while (true) { 502 async_usleep(1000 * 10); 503 504 sess_rc = usb_endpoint_pipe_start_session(&kbd_dev->poll_pipe); 505 if (sess_rc != EOK) { 506 printf("Failed to start a session: %s.\n", 507 str_error(sess_rc)); 508 continue; 509 } 510 511 rc = usb_endpoint_pipe_read(&kbd_dev->poll_pipe, buffer, 512 BUFFER_SIZE, &actual_size); 513 sess_rc = usb_endpoint_pipe_end_session(&kbd_dev->poll_pipe); 514 515 if (rc != EOK) { 516 printf("Error polling the keyboard: %s.\n", 517 str_error(rc)); 518 continue; 519 } 520 521 if (sess_rc != EOK) { 522 printf("Error closing session: %s.\n", 523 str_error(sess_rc)); 524 continue; 525 } 526 527 /* 528 * If the keyboard answered with NAK, it returned no data. 529 * This implies that no change happened since last query. 530 */ 531 if (actual_size == 0) { 532 printf("Keyboard returned NAK\n"); 533 continue; 534 } 535 536 /* 537 * TODO: Process pressed keys. 538 */ 539 printf("Calling usbkbd_process_interrupt_in()\n"); 540 usbkbd_process_interrupt_in(kbd_dev, buffer, actual_size); 541 } 542 543 // not reached 544 assert(0); 545 } 546 547 static int usbkbd_fibril_device(void *arg) 548 { 549 printf("!!! USB device fibril\n"); 550 551 if (arg == NULL) { 552 printf("No device!\n"); 553 return -1; 554 } 555 556 ddf_dev_t *dev = (ddf_dev_t *)arg; 557 558 // initialize device (get and process descriptors, get address, etc.) 559 usb_hid_dev_kbd_t *kbd_dev = usbkbd_init_device(dev); 560 if (kbd_dev == NULL) { 561 printf("Error while initializing device.\n"); 562 return -1; 563 } 564 565 usbkbd_poll_keyboard(kbd_dev); 566 567 return EOK; 568 } 569 570 static int usbkbd_add_device(ddf_dev_t *dev) 571 { 572 /* For now, fail immediately. */ 573 //return ENOTSUP; 574 575 /* 576 * When everything is okay, connect to "our" HC. 577 * 578 * Not supported yet, skip.. 579 */ 580 // int phone = usb_drv_hc_connect_auto(dev, 0); 581 // if (phone < 0) { 582 // /* 583 // * Connecting to HC failed, roll-back and announce 584 // * failure. 585 // */ 586 // return phone; 587 // } 588 589 // dev->parent_phone = phone; 590 591 /* 592 * Create default function. 593 */ 594 // FIXME - check for errors 595 ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard"); 596 assert(kbd_fun != NULL); 597 kbd_fun->ops = &keyboard_ops; 598 599 int rc = ddf_fun_bind(kbd_fun); 600 assert(rc == EOK); 601 rc = ddf_fun_add_to_class(kbd_fun, "keyboard"); 602 assert(rc == EOK); 603 604 /* 605 * Create new fibril for handling this keyboard 606 */ 607 fid_t fid = fibril_create(usbkbd_fibril_device, dev); 608 if (fid == 0) { 609 printf("%s: failed to start fibril for HID device\n", NAME); 610 return ENOMEM; 611 } 612 fibril_add_ready(fid); 613 614 //dev->ops = &keyboard_ops; 615 (void)keyboard_ops; 616 617 //add_device_to_class(dev, "keyboard"); 618 619 /* 620 * Hurrah, device is initialized. 621 */ 622 return EOK; 623 } 66 624 67 625 static driver_ops_t kbd_driver_ops = { 68 .add_device = usb hid_add_device,626 .add_device = usbkbd_add_device, 69 627 }; 70 71 /*----------------------------------------------------------------------------*/72 628 73 629 static driver_t kbd_driver = { … … 76 632 }; 77 633 78 /*----------------------------------------------------------------------------*/79 80 634 int main(int argc, char *argv[]) 81 635 { 82 usb_log_enable(USB_LOG_LEVEL_INFO, NAME);636 usb_log_enable(USB_LOG_LEVEL_INFO, "usbhid"); 83 637 return ddf_driver_main(&kbd_driver); 84 638 } -
uspace/drv/usbhid/usbhid.ma
r8c877b2 rdff940f8 1 100 usb&interface&class=HID&subclass=0x01&protocol=0x01 1 10 usb&class=hid 2 10 usb&class=HID 2 3 10 usb&interface&class=HID 4 10 usb&hid -
uspace/drv/usbhub/usbhub.c
r8c877b2 rdff940f8 149 149 } 150 150 151 / * Retrieve full configuration descriptor. */152 uint8_t *descriptors = NULL;153 size_t descriptors_size = 0;154 opResult = usb_request_get_ full_configuration_descriptor_alloc(151 //configuration descriptor 152 /// \TODO check other configurations? 153 usb_standard_configuration_descriptor_t config_descriptor; 154 opResult = usb_request_get_bare_configuration_descriptor( 155 155 &hub->endpoints.control, 0, 156 (void **) &descriptors, &descriptors_size); 157 if (opResult != EOK) { 158 usb_log_error("Could not get configuration descriptor: %s.\n", 159 str_error(opResult)); 156 &config_descriptor); 157 if(opResult!=EOK){ 158 dprintf(USB_LOG_LEVEL_ERROR, "could not get configuration descriptor, %d",opResult); 160 159 return opResult; 161 160 } 162 usb_standard_configuration_descriptor_t *config_descriptor 163 = (usb_standard_configuration_descriptor_t *) descriptors; 164 165 /* Set configuration. */ 161 //set configuration 166 162 opResult = usb_request_set_configuration(&hub->endpoints.control, 167 config_descriptor->configuration_number); 168 169 if (opResult != EOK) { 170 usb_log_error("Failed to set hub configuration: %s.\n", 171 str_error(opResult)); 163 config_descriptor.configuration_number); 164 165 if (opResult != EOK) { 166 dprintf(USB_LOG_LEVEL_ERROR, 167 "something went wrong when setting hub`s configuration, %d", 168 opResult); 172 169 return opResult; 173 170 } 174 171 dprintf(USB_LOG_LEVEL_DEBUG, "\tused configuration %d", 175 config_descriptor->configuration_number); 172 config_descriptor.configuration_number); 173 174 //full configuration descriptor 175 size_t transferred = 0; 176 uint8_t * descriptors = (uint8_t *)malloc(config_descriptor.total_length); 177 if (descriptors == NULL) { 178 dprintf(USB_LOG_LEVEL_ERROR, "insufficient memory"); 179 return ENOMEM; 180 } 181 opResult = usb_request_get_full_configuration_descriptor(&hub->endpoints.control, 182 0, descriptors, 183 config_descriptor.total_length, &transferred); 184 if(opResult!=EOK){ 185 free(descriptors); 186 dprintf(USB_LOG_LEVEL_ERROR, 187 "could not get full configuration descriptor, %d",opResult); 188 return opResult; 189 } 190 if (transferred != config_descriptor.total_length) { 191 dprintf(USB_LOG_LEVEL_ERROR, 192 "received incorrect full configuration descriptor"); 193 return ELIMIT; 194 } 176 195 177 196 usb_endpoint_mapping_t endpoint_mapping[1] = { … … 185 204 opResult = usb_endpoint_pipe_initialize_from_configuration( 186 205 endpoint_mapping, 1, 187 descriptors, descriptors_size,206 descriptors, config_descriptor.total_length, 188 207 &hub->device_connection); 189 208 if (opResult != EOK) { … … 234 253 usb_endpoint_pipe_start_session(&result->endpoints.control); 235 254 opResult = usb_request_get_descriptor(&result->endpoints.control, 236 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_DEVICE, 237 USB_DESCTYPE_HUB, 238 0, 0, serialized_descriptor, 255 USB_REQUEST_TYPE_CLASS, 256 USB_DESCTYPE_HUB, 0, 0, serialized_descriptor, 239 257 USB_HUB_MAX_DESCRIPTOR_SIZE, &received_size); 240 258 usb_endpoint_pipe_end_session(&result->endpoints.control); -
uspace/drv/usbmid/explore.c
r8c877b2 rdff940f8 42 42 #include "usbmid.h" 43 43 44 /** Allocate and retrieve full configuration descriptor. 45 * 46 * @param[in] dev USB device. 47 * @param[in] config_index Configuration index. 48 * @param[out] size Pointer where to store size of the allocated buffer. 49 * @return Allocated full configuration descriptor. 50 * @retval NULL Error occured. 51 */ 52 static void *get_configuration_descriptor(usbmid_device_t *dev, 53 size_t config_index, size_t *size) 54 { 55 usb_standard_configuration_descriptor_t config_descriptor; 56 int rc = usb_request_get_bare_configuration_descriptor(&dev->ctrl_pipe, 57 config_index, &config_descriptor); 58 if (rc != EOK) { 59 usb_log_error("Failed getting configuration descriptor: %s.\n", 60 str_error(rc)); 61 return NULL; 62 } 63 64 void *full_config_descriptor = malloc(config_descriptor.total_length); 65 if (full_config_descriptor == NULL) { 66 usb_log_fatal("Out of memory (wanted: %zuB).\n", 67 (size_t) config_descriptor.total_length); 68 return NULL; 69 } 70 71 size_t full_config_descriptor_size; 72 rc = usb_request_get_full_configuration_descriptor(&dev->ctrl_pipe, 73 config_index, 74 full_config_descriptor, config_descriptor.total_length, 75 &full_config_descriptor_size); 76 if (rc != EOK) { 77 usb_log_error("Failed getting configuration descriptor: %s.\n", 78 str_error(rc)); 79 free(full_config_descriptor); 80 return NULL; 81 } 82 83 if (full_config_descriptor_size != config_descriptor.total_length) { 84 usb_log_error("Failed getting full configuration descriptor.\n"); 85 free(full_config_descriptor); 86 return NULL; 87 } 88 89 if (size != NULL) { 90 *size = full_config_descriptor_size; 91 } 92 93 return full_config_descriptor; 94 } 95 44 96 /** Find starting indexes of all interface descriptors in a configuration. 45 97 * … … 126 178 127 179 size_t config_descriptor_size; 128 uint8_t *config_descriptor_raw = NULL; 129 rc = usb_request_get_full_configuration_descriptor_alloc( 130 &dev->ctrl_pipe, 0, 131 (void **) &config_descriptor_raw, &config_descriptor_size); 132 if (rc != EOK) { 133 usb_log_error("Failed getting full config descriptor: %s.\n", 134 str_error(rc)); 180 uint8_t *config_descriptor_raw = get_configuration_descriptor(dev, 0, 181 &config_descriptor_size); 182 if (config_descriptor_raw == NULL) { 135 183 return false; 136 184 } … … 159 207 } 160 208 161 /* Select the first configuration */162 rc = usb_request_set_configuration(&dev->ctrl_pipe,163 config_descriptor->configuration_number);164 if (rc != EOK) {165 usb_log_error("Failed to set device configuration: %s.\n",166 str_error(rc));167 free(config_descriptor_raw);168 free(interface_descriptors);169 return false;170 }171 172 173 /* Create control function */174 209 ddf_fun_t *ctl_fun = ddf_fun_create(dev->dev, fun_exposed, "ctl"); 175 210 if (ctl_fun == NULL) { … … 188 223 } 189 224 190 /* Spawn interface children */191 225 size_t i; 192 226 for (i = 0; i < interface_descriptors_count; i++) { -
uspace/lib/c/generic/loader.c
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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
r8c877b2 rdff940f8 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/lib/usb/include/usb/classes/hid.h
r8c877b2 rdff940f8 51 51 } usb_hid_request_t; 52 52 53 typedef enum {54 USB_HID_REPORT_TYPE_INPUT = 1,55 USB_HID_REPORT_TYPE_OUTPUT = 2,56 USB_HID_REPORT_TYPE_FEATURE = 357 } usb_hid_report_type_t;58 59 typedef enum {60 USB_HID_PROTOCOL_BOOT = 0,61 USB_HID_PROTOCOL_REPORT = 162 } usb_hid_protocol_t;63 64 53 /** USB/HID subclass constants. */ 65 54 typedef enum { … … 73 62 USB_HID_PROTOCOL_KEYBOARD = 1, 74 63 USB_HID_PROTOCOL_MOUSE = 2 75 } usb_hid_ iface_protocol_t;64 } usb_hid_protocol_t; 76 65 77 66 /** Part of standard USB HID descriptor specifying one class descriptor. -
uspace/lib/usb/include/usb/classes/hidparser.h
r8c877b2 rdff940f8 70 70 } usb_hid_report_in_callbacks_t; 71 71 72 73 typedef enum { 74 USB_HID_MOD_LCTRL = 0x01, 75 USB_HID_MOD_LSHIFT = 0x02, 76 USB_HID_MOD_LALT = 0x04, 77 USB_HID_MOD_LGUI = 0x08, 78 USB_HID_MOD_RCTRL = 0x10, 79 USB_HID_MOD_RSHIFT = 0x20, 80 USB_HID_MOD_RALT = 0x40, 81 USB_HID_MOD_RGUI = 0x80, 82 USB_HID_MOD_COUNT = 8 83 } usb_hid_modifiers_t; 84 85 typedef enum { 86 USB_HID_LED_NUM_LOCK = 0x1, 87 USB_HID_LED_CAPS_LOCK = 0x2, 88 USB_HID_LED_SCROLL_LOCK = 0x4, 89 USB_HID_LED_COMPOSE = 0x8, 90 USB_HID_LED_KANA = 0x10, 91 USB_HID_LED_COUNT = 5 92 } usb_hid_led_t; 93 94 static const usb_hid_modifiers_t 95 usb_hid_modifiers_consts[USB_HID_MOD_COUNT] = { 96 USB_HID_MOD_LCTRL, 97 USB_HID_MOD_LSHIFT, 98 USB_HID_MOD_LALT, 99 USB_HID_MOD_LGUI, 100 USB_HID_MOD_RCTRL, 101 USB_HID_MOD_RSHIFT, 102 USB_HID_MOD_RALT, 103 USB_HID_MOD_RGUI 104 }; 105 106 //static const usb_hid_led_t usb_hid_led_consts[USB_HID_LED_COUNT] = { 107 // USB_HID_LED_NUM_LOCK, 108 // USB_HID_LED_CAPS_LOCK, 109 // USB_HID_LED_SCROLL_LOCK, 110 // USB_HID_LED_COMPOSE, 111 // USB_HID_LED_KANA 112 //}; 113 114 //#define USB_HID_BOOT_KEYBOARD_NUM_LOCK 0x01 115 //#define USB_HID_BOOT_KEYBOARD_CAPS_LOCK 0x02 116 //#define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK 0x04 117 //#define USB_HID_BOOT_KEYBOARD_COMPOSE 0x08 118 //#define USB_HID_BOOT_KEYBOARD_KANA 0x10 72 #define USB_HID_BOOT_KEYBOARD_NUM_LOCK 0x01 73 #define USB_HID_BOOT_KEYBOARD_CAPS_LOCK 0x02 74 #define USB_HID_BOOT_KEYBOARD_SCROLL_LOCK 0x04 75 #define USB_HID_BOOT_KEYBOARD_COMPOSE 0x08 76 #define USB_HID_BOOT_KEYBOARD_KANA 0x10 119 77 120 78 /* -
uspace/lib/usb/include/usb/request.h
r8c877b2 rdff940f8 96 96 int usb_request_set_address(usb_endpoint_pipe_t *, usb_address_t); 97 97 int usb_request_get_descriptor(usb_endpoint_pipe_t *, usb_request_type_t, 98 usb_request_recipient_t, uint8_t, uint8_t, uint16_t, void *, size_t, 99 size_t *); 98 uint8_t, uint8_t, uint16_t, void *, size_t, size_t *); 100 99 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t *, usb_request_type_t, 101 u sb_request_recipient_t, uint8_t, uint8_t, uint16_t, void **, size_t *);100 uint8_t, uint8_t, uint16_t, void **, size_t *); 102 101 int usb_request_get_device_descriptor(usb_endpoint_pipe_t *, 103 102 usb_standard_device_descriptor_t *); … … 106 105 int usb_request_get_full_configuration_descriptor(usb_endpoint_pipe_t *, int, 107 106 void *, size_t, size_t *); 108 int usb_request_get_full_configuration_descriptor_alloc(usb_endpoint_pipe_t *,109 int, void **, size_t *);110 107 int usb_request_set_configuration(usb_endpoint_pipe_t *, uint8_t); 111 108 -
uspace/lib/usb/src/hidparser.c
r8c877b2 rdff940f8 144 144 int usb_hid_boot_keyboard_output_report(uint8_t leds, uint8_t *data, size_t size) 145 145 { 146 if (size <1){146 if(size != 1){ 147 147 return -1; 148 148 } 149 149 150 data[0] = leds; 150 /* used only first five bits, others are only padding*/ 151 *data = leds; 151 152 return EOK; 152 153 } -
uspace/lib/usb/src/request.c
r8c877b2 rdff940f8 36 36 #include <errno.h> 37 37 #include <assert.h> 38 #include <usb/debug.h>39 38 40 39 #define MAX_DATA_LENGTH ((size_t)(0xFFFF)) … … 210 209 */ 211 210 int usb_request_get_descriptor(usb_endpoint_pipe_t *pipe, 212 usb_request_type_t request_type, usb_request_recipient_t recipient,211 usb_request_type_t request_type, 213 212 uint8_t descriptor_type, uint8_t descriptor_index, 214 213 uint16_t language, … … 225 224 226 225 return usb_control_request_get(pipe, 227 request_type, recipient,226 request_type, USB_REQUEST_RECIPIENT_DEVICE, 228 227 USB_DEVREQ_GET_DESCRIPTOR, 229 228 wValue, language, … … 243 242 */ 244 243 int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe, 245 usb_request_type_t request_type, usb_request_recipient_t recipient,244 usb_request_type_t request_type, 246 245 uint8_t descriptor_type, uint8_t descriptor_index, 247 246 uint16_t language, … … 259 258 uint8_t tmp_buffer[1]; 260 259 size_t bytes_transfered; 261 rc = usb_request_get_descriptor(pipe, request_type, recipient,260 rc = usb_request_get_descriptor(pipe, request_type, 262 261 descriptor_type, descriptor_index, language, 263 262 &tmp_buffer, 1, &bytes_transfered); … … 284 283 } 285 284 286 rc = usb_request_get_descriptor(pipe, request_type, recipient,285 rc = usb_request_get_descriptor(pipe, request_type, 287 286 descriptor_type, descriptor_index, language, 288 287 buffer, size, &bytes_transfered); … … 321 320 usb_standard_device_descriptor_t descriptor_tmp; 322 321 int rc = usb_request_get_descriptor(pipe, 323 USB_REQUEST_TYPE_STANDARD, USB_ REQUEST_RECIPIENT_DEVICE,324 USB_DESCTYPE_DEVICE,0, 0,322 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_DEVICE, 323 0, 0, 325 324 &descriptor_tmp, sizeof(descriptor_tmp), 326 325 &actually_transferred); … … 367 366 usb_standard_configuration_descriptor_t descriptor_tmp; 368 367 int rc = usb_request_get_descriptor(pipe, 369 USB_REQUEST_TYPE_STANDARD, USB_ REQUEST_RECIPIENT_DEVICE,370 USB_DESCTYPE_CONFIGURATION,index, 0,368 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION, 369 index, 0, 371 370 &descriptor_tmp, sizeof(descriptor_tmp), 372 371 &actually_transferred); … … 407 406 408 407 return usb_request_get_descriptor(pipe, 409 USB_REQUEST_TYPE_STANDARD, USB_ REQUEST_RECIPIENT_DEVICE,410 USB_DESCTYPE_CONFIGURATION,index, 0,408 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_CONFIGURATION, 409 index, 0, 411 410 descriptor, descriptor_size, actual_size); 412 }413 414 /** Retrieve full configuration descriptor, allocate space for it.415 *416 * The function takes care that full configuration descriptor is returned417 * (i.e. the function will fail when less data then descriptor.totalLength418 * is returned).419 *420 * @param[in] pipe Control endpoint pipe (session must be already started).421 * @param[in] index Configuration index.422 * @param[out] descriptor_ptr Where to store pointer to allocated buffer.423 * @param[out] descriptor_size Where to store the size of the descriptor.424 * @return Error code.425 */426 int usb_request_get_full_configuration_descriptor_alloc(427 usb_endpoint_pipe_t *pipe, int index,428 void **descriptor_ptr, size_t *descriptor_size)429 {430 int rc;431 432 if (descriptor_ptr == NULL) {433 return EBADMEM;434 }435 436 usb_standard_configuration_descriptor_t bare_config;437 rc = usb_request_get_bare_configuration_descriptor(pipe, index,438 &bare_config);439 if (rc != EOK) {440 return rc;441 }442 443 if (bare_config.descriptor_type != USB_DESCTYPE_CONFIGURATION) {444 return ENOENT;445 }446 if (bare_config.total_length < sizeof(bare_config)) {447 return ELIMIT;448 }449 450 void *buffer = malloc(bare_config.total_length);451 if (buffer == NULL) {452 return ENOMEM;453 }454 455 size_t transferred = 0;456 rc = usb_request_get_full_configuration_descriptor(pipe, index,457 buffer, bare_config.total_length, &transferred);458 if (rc != EOK) {459 free(buffer);460 return rc;461 }462 463 if (transferred != bare_config.total_length) {464 free(buffer);465 return ELIMIT;466 }467 468 /* Everything looks okay, copy the pointers. */469 470 *descriptor_ptr = buffer;471 472 if (descriptor_size != NULL) {473 *descriptor_size = bare_config.total_length;474 }475 476 return EOK;477 411 } 478 412 … … 518 452 size_t string_descriptor_size = 0; 519 453 rc = usb_request_get_descriptor_alloc(pipe, 520 USB_REQUEST_TYPE_STANDARD, USB_REQUEST_RECIPIENT_DEVICE, 521 USB_DESCTYPE_STRING, 0, 0, 454 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0, 522 455 (void **) &string_descriptor, &string_descriptor_size); 523 456 if (rc != EOK) { … … 569 502 * 570 503 * @param[in] pipe Control endpoint pipe (session must be already started). 571 * @param[in] index String index (in native endianess), 572 * first index has number 1 (index from descriptors can be used directly). 504 * @param[in] index String index (in native endianess). 573 505 * @param[in] lang String language (in native endianess). 574 506 * @param[out] string_ptr Where to store allocated string in native encoding. … … 581 513 return EBADMEM; 582 514 } 583 /* 584 * Index is actually one byte value and zero index is used 585 * to retrieve list of supported languages. 586 */ 587 if ((index < 1) || (index > 0xFF)) { 515 /* Index is actually one byte value. */ 516 if (index > 0xFF) { 588 517 return ERANGE; 589 518 } … … 602 531 size_t string_size; 603 532 rc = usb_request_get_descriptor_alloc(pipe, 604 USB_REQUEST_TYPE_STANDARD, USB_ REQUEST_RECIPIENT_DEVICE,605 USB_DESCTYPE_STRING,index, uint16_host2usb(lang),533 USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 534 index, uint16_host2usb(lang), 606 535 (void **) &string, &string_size); 607 536 if (rc != EOK) { -
uspace/srv/devmap/devmap.c
r8c877b2 rdff940f8 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_dentry.c
r8c877b2 rdff940f8 42 42 static bool is_d_char(const char ch) 43 43 { 44 if (isalnum(ch) || ch == '_' || ch == '-')44 if (isalnum(ch) || ch == '_') 45 45 return true; 46 46 else -
uspace/srv/fs/fat/fat_ops.c
r8c877b2 rdff940f8 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); -
uspace/srv/hid/console/console.c
r8c877b2 rdff940f8 41 41 #include <ipc/ns.h> 42 42 #include <errno.h> 43 #include <str_error.h>44 43 #include <ipc/console.h> 45 44 #include <unistd.h> … … 65 64 #define NAME "console" 66 65 #define NAMESPACE "term" 67 /** Interval for checking for new keyboard (1/4s). */68 #define HOTPLUG_WATCH_INTERVAL (1000 * 250)69 66 70 67 /** Phone to the keyboard driver. */ … … 715 712 } 716 713 717 static int connect_keyboard_or_mouse(const char *devname, 718 async_client_conn_t handler, const char *path) 714 static int connect_keyboard(char *path) 719 715 { 720 716 int fd = open(path, O_RDONLY); … … 729 725 } 730 726 731 int rc = async_connect_to_me(phone, SERVICE_CONSOLE, 0, 0, handler); 727 /* NB: The callback connection is slotted for removal */ 728 sysarg_t phonehash; 729 sysarg_t taskhash; 730 int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE, 731 0, 0, NULL, NULL, NULL, &taskhash, &phonehash); 732 732 if (rc != EOK) { 733 printf(NAME ": " \ 734 "Failed to create callback from input device: %s.\n", 735 str_error(rc)); 733 printf(NAME ": Failed to create callback from input device\n"); 736 734 return rc; 737 735 } 738 736 739 printf(NAME ": found %s \"%s\".\n", devname, path); 737 async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events); 738 739 printf(NAME ": we got a hit (new keyboard \"%s\").\n", path); 740 740 741 741 return phone; 742 742 } 743 743 744 static int connect_keyboard(const char *path) 745 { 746 return connect_keyboard_or_mouse("keyboard", keyboard_events, path); 747 } 748 749 static int connect_mouse(const char *path) 750 { 751 return connect_keyboard_or_mouse("mouse", mouse_events, path); 752 } 753 754 struct hid_class_info { 755 char *classname; 756 int (*connection_func)(const char *); 757 }; 758 759 /** Periodically check for new keyboards in /dev/class/. 744 /** Try to connect to given keyboard, bypassing provided libc routines. 760 745 * 761 * @param arg Class name.762 * @return This function should never exit.746 * @param devmap_path Path to keyboard without /dev prefix. 747 * @return Phone or error code. 763 748 */ 764 static int check_new_device_fibril(void *arg) 765 { 766 struct hid_class_info *dev_info = arg; 767 768 size_t index = 1; 749 static int connect_keyboard_bypass(char *devmap_path) 750 { 751 int devmap_phone = async_connect_me_to_blocking(PHONE_NS, 752 SERVICE_DEVMAP, DEVMAP_CLIENT, 0); 753 if (devmap_phone < 0) { 754 return devmap_phone; 755 } 756 ipc_call_t answer; 757 aid_t req = async_send_2(devmap_phone, DEVMAP_DEVICE_GET_HANDLE, 758 0, 0, &answer); 759 760 sysarg_t retval = async_data_write_start(devmap_phone, 761 devmap_path, str_size(devmap_path)); 762 if (retval != EOK) { 763 async_wait_for(req, NULL); 764 async_hangup(devmap_phone); 765 return retval; 766 } 767 768 async_wait_for(req, &retval); 769 770 if (retval != EOK) { 771 async_hangup(devmap_phone); 772 return retval; 773 } 774 775 devmap_handle_t handle = (devmap_handle_t) IPC_GET_ARG1(answer); 776 777 async_hangup(devmap_phone); 778 779 int phone = async_connect_me_to(PHONE_NS, 780 SERVICE_DEVMAP, DEVMAP_CONNECT_TO_DEVICE, handle); 781 if (phone < 0) { 782 return phone; 783 } 784 785 /* NB: The callback connection is slotted for removal */ 786 sysarg_t phonehash; 787 sysarg_t taskhash; 788 int rc = async_req_3_5(phone, IPC_M_CONNECT_TO_ME, SERVICE_CONSOLE, 789 0, 0, NULL, NULL, NULL, &taskhash, &phonehash); 790 if (rc != EOK) { 791 printf(NAME ": Failed to create callback from input device\n"); 792 return rc; 793 } 794 795 async_new_connection(taskhash, phonehash, 0, NULL, keyboard_events); 796 797 printf(NAME ": we got a hit (new keyboard \"/dev/%s\").\n", 798 devmap_path); 799 800 return phone; 801 } 802 803 804 static int check_new_keyboards(void *arg) 805 { 806 char *class_name = (char *) arg; 807 808 int index = 1; 769 809 770 810 while (true) { 771 async_usleep( HOTPLUG_WATCH_INTERVAL);811 async_usleep(1 * 500 * 1000); 772 812 char *path; 773 int rc = asprintf(&path, "/dev/class/%s\\%zu", 774 dev_info->classname, index); 813 int rc = asprintf(&path, "class/%s\\%d", class_name, index); 775 814 if (rc < 0) { 776 815 continue; 777 816 } 778 817 rc = 0; 779 rc = dev_info->connection_func(path);818 rc = connect_keyboard_bypass(path); 780 819 if (rc > 0) { 781 820 /* We do not allow unplug. */ … … 792 831 /** Start a fibril monitoring hot-plugged keyboards. 793 832 */ 794 static void check_new_devices_in_background(int (*connection_func)(const char *), 795 const char *classname) 796 { 797 struct hid_class_info *dev_info = malloc(sizeof(struct hid_class_info)); 798 if (dev_info == NULL) { 799 printf(NAME ": " \ 800 "out of memory, will not start hot-plug-watch fibril.\n"); 801 return; 802 } 803 int rc; 804 805 rc = asprintf(&dev_info->classname, "%s", classname); 806 if (rc < 0) { 807 printf(NAME ": failed to format classname: %s.\n", 808 str_error(rc)); 809 return; 810 } 811 dev_info->connection_func = connection_func; 812 813 fid_t fid = fibril_create(check_new_device_fibril, (void *)dev_info); 833 static void check_new_keyboards_in_background() 834 { 835 fid_t fid = fibril_create(check_new_keyboards, (void *)"keyboard"); 814 836 if (!fid) { 815 printf(NAME 816 ": failed to create hot-plug-watch fibril for %s.\n", 817 classname); 837 printf(NAME ": failed to create hot-plug-watch fibril.\n"); 818 838 return; 819 839 } … … 829 849 } 830 850 831 mouse_phone = connect_mouse("/dev/hid_in/mouse"); 851 /* Connect to mouse device */ 852 mouse_phone = -1; 853 int mouse_fd = open("/dev/hid_in/mouse", O_RDONLY); 854 855 if (mouse_fd < 0) { 856 printf(NAME ": Notice - failed opening %s\n", "/dev/hid_in/mouse"); 857 goto skip_mouse; 858 } 859 860 mouse_phone = fd_phone(mouse_fd); 832 861 if (mouse_phone < 0) { 833 printf(NAME ": Failed to connect to mouse device: %s.\n", 834 str_error(mouse_phone)); 835 } 862 printf(NAME ": Failed to connect to mouse device\n"); 863 goto skip_mouse; 864 } 865 866 if (async_connect_to_me(mouse_phone, SERVICE_CONSOLE, 0, 0, mouse_events) 867 != 0) { 868 printf(NAME ": Failed to create callback from mouse device\n"); 869 mouse_phone = -1; 870 goto skip_mouse; 871 } 872 873 skip_mouse: 836 874 837 875 /* Connect to framebuffer driver */ … … 917 955 918 956 /* Start fibril for checking on hot-plugged keyboards. */ 919 check_new_devices_in_background(connect_keyboard, "keyboard"); 920 check_new_devices_in_background(connect_mouse, "mouse"); 957 check_new_keyboards_in_background(); 921 958 922 959 return true;
Note:
See TracChangeset
for help on using the changeset viewer.