Changeset f97717d9 in mainline
- Timestamp:
- 2011-03-25T16:22:14Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- da3dafc, e6223239
- Parents:
- d8421c4 (diff), f08c560 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 4 deleted
- 36 edited
- 21 moved
Legend:
- Unmodified
- Added
- Removed
-
.bzrignore
rd8421c4 rf97717d9 9 9 _link.ld 10 10 ./*.iso 11 12 ./tools/__pycache__/ 11 13 12 14 ./Makefile.common … … 139 141 .cproject 140 142 .project 143 .settings 144 .pydevproject 145 -
HelenOS.config
rd8421c4 rf97717d9 552 552 ! CONFIG_RUN_VIRTUAL_USB_HC (n/y) 553 553 554 % Polling UHCI & OHCI (no interrupts) 555 ! [PLATFORM=ia32|PLATFORM=amd64] CONFIG_USBHC_NO_INTERRUPTS (y/n) -
boot/arch/amd64/Makefile.inc
rd8421c4 rf97717d9 49 49 usbflbk \ 50 50 usbhub \ 51 usb hid \51 usbkbd \ 52 52 usbmid \ 53 53 usbmouse \ -
uspace/Makefile
rd8421c4 rf97717d9 122 122 drv/uhci-rhd \ 123 123 drv/usbflbk \ 124 drv/usb hid \124 drv/usbkbd \ 125 125 drv/usbhub \ 126 126 drv/usbmid \ … … 142 142 drv/uhci-rhd \ 143 143 drv/usbflbk \ 144 drv/usb hid \144 drv/usbkbd \ 145 145 drv/usbhub \ 146 146 drv/usbmid \ -
uspace/app/usbinfo/info.c
rd8421c4 rf97717d9 294 294 } 295 295 296 297 void dump_status(usbinfo_device_t *dev) 298 { 299 int rc; 300 uint16_t device_status = 0; 301 uint16_t ctrl_pipe_status = 0; 302 303 /* Device status first. */ 304 rc = usb_request_get_status(&dev->ctrl_pipe, 305 USB_REQUEST_RECIPIENT_DEVICE, 0, 306 &device_status); 307 if (rc != EOK) { 308 printf("%sFailed to get device status: %s.\n", 309 get_indent(0), str_error(rc)); 310 goto try_ctrl_pipe_status; 311 } 312 313 printf("%sDevice status 0x%04x: power=%s, remote-wakeup=%s.\n", 314 get_indent(0), 315 device_status, 316 device_status & USB_DEVICE_STATUS_SELF_POWERED ? "self" : "bus", 317 device_status & USB_DEVICE_STATUS_REMOTE_WAKEUP ? "yes" : "no"); 318 319 /* Interface is not interesting, skipping ;-). */ 320 321 /* Control endpoint zero. */ 322 try_ctrl_pipe_status: 323 rc = usb_request_get_status(&dev->ctrl_pipe, 324 USB_REQUEST_RECIPIENT_ENDPOINT, 0, 325 &ctrl_pipe_status); 326 if (rc != EOK) { 327 printf("%sFailed to get control endpoint status: %s.\n", 328 get_indent(0), str_error(rc)); 329 goto leave; 330 } 331 332 printf("%sControl endpoint zero status %04X: halted=%s.\n", 333 get_indent(0), 334 ctrl_pipe_status, 335 ctrl_pipe_status & USB_ENDPOINT_STATUS_HALTED ? "yes" : "no"); 336 337 leave: 338 return; 339 } 340 296 341 /** @} 297 342 */ -
uspace/app/usbinfo/main.c
rd8421c4 rf97717d9 136 136 _OPTION("-T --descriptor-tree-full", "Print detailed descriptor tree"); 137 137 _OPTION("-s --strings", "Try to print all string descriptors."); 138 _OPTION("-S --status", "Get status of the device."); 138 139 139 140 printf("\n"); … … 152 153 {"descriptor-tree-full", no_argument, NULL, 'T'}, 153 154 {"strings", no_argument, NULL, 's'}, 155 {"status", no_argument, NULL, 'S'}, 154 156 {0, 0, NULL, 0} 155 157 }; 156 static const char *short_options = "himtTs ";158 static const char *short_options = "himtTsS"; 157 159 158 160 static usbinfo_action_t actions[] = { … … 180 182 .opt = 's', 181 183 .action = dump_strings, 184 .active = false 185 }, 186 { 187 .opt = 'S', 188 .action = dump_status, 182 189 .active = false 183 190 }, -
uspace/app/usbinfo/usbinfo.h
rd8421c4 rf97717d9 84 84 void dump_descriptor_tree_full(usbinfo_device_t *); 85 85 void dump_strings(usbinfo_device_t *); 86 void dump_status(usbinfo_device_t *); 86 87 87 88 -
uspace/drv/ehci-hcd/main.c
rd8421c4 rf97717d9 119 119 int main(int argc, char *argv[]) 120 120 { 121 usb_log_enable(USB_LOG_LEVEL_DE BUG, NAME);121 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 122 122 return ddf_driver_main(&ehci_driver); 123 123 } -
uspace/drv/ohci/batch.c
rd8421c4 rf97717d9 118 118 instance->next_step = batch_call_in_and_dispose; 119 119 /* TODO: implement */ 120 usb_log_debug("Batch(%p) CONTROL WRITEinitialized.\n", instance);120 usb_log_debug("Batch(%p) CONTROL READ initialized.\n", instance); 121 121 } 122 122 /*----------------------------------------------------------------------------*/ -
uspace/drv/ohci/iface.c
rd8421c4 rf97717d9 33 33 */ 34 34 #include <ddf/driver.h> 35 #include <ddf/interrupt.h>36 #include <device/hw_res.h>37 35 #include <errno.h> 38 #include <str_error.h> 39 40 #include <usb_iface.h> 41 #include <usb/ddfiface.h> 36 42 37 #include <usb/debug.h> 43 38 … … 60 55 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) 61 56 { 62 63 64 65 66 67 57 assert(fun); 58 hc_t *hc = fun_to_hc(fun); 59 assert(hc); 60 usb_log_debug("Default address request with speed %d.\n", speed); 61 usb_device_keeper_reserve_default_address(&hc->manager, speed); 62 return EOK; 68 63 } 69 64 /*----------------------------------------------------------------------------*/ … … 75 70 static int release_default_address(ddf_fun_t *fun) 76 71 { 77 78 79 80 81 82 72 assert(fun); 73 hc_t *hc = fun_to_hc(fun); 74 assert(hc); 75 usb_log_debug("Default address release.\n"); 76 usb_device_keeper_release_default_address(&hc->manager); 77 return EOK; 83 78 } 84 79 /*----------------------------------------------------------------------------*/ … … 90 85 * @return Error code. 91 86 */ 92 static int request_address( ddf_fun_t *fun, usb_speed_t speed,93 usb_address_t *address)94 { 95 96 97 98 99 100 101 102 103 104 105 87 static int request_address( 88 ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address) 89 { 90 assert(fun); 91 hc_t *hc = fun_to_hc(fun); 92 assert(hc); 93 assert(address); 94 95 usb_log_debug("Address request with speed %d.\n", speed); 96 *address = device_keeper_get_free_address(&hc->manager, speed); 97 usb_log_debug("Address request with result: %d.\n", *address); 98 if (*address <= 0) 99 return *address; 100 return EOK; 106 101 } 107 102 /*----------------------------------------------------------------------------*/ … … 113 108 * @return Error code. 114 109 */ 115 static int bind_address( ddf_fun_t *fun,116 usb_address_t address, devman_handle_t handle)117 { 118 119 120 121 122 123 110 static int bind_address( 111 ddf_fun_t *fun, usb_address_t address, devman_handle_t handle) 112 { 113 assert(fun); 114 hc_t *hc = fun_to_hc(fun); 115 assert(hc); 116 usb_log_debug("Address bind %d-%d.\n", address, handle); 117 usb_device_keeper_bind(&hc->manager, address, handle); 118 return EOK; 124 119 } 125 120 /*----------------------------------------------------------------------------*/ … … 132 127 static int release_address(ddf_fun_t *fun, usb_address_t address) 133 128 { 134 135 136 137 138 139 140 } 141 129 assert(fun); 130 hc_t *hc = fun_to_hc(fun); 131 assert(hc); 132 usb_log_debug("Address release %d.\n", address); 133 usb_device_keeper_release(&hc->manager, address); 134 return EOK; 135 } 136 /*----------------------------------------------------------------------------*/ 142 137 /** Register endpoint for bandwidth reservation. 143 138 * … … 151 146 * @return Error code. 152 147 */ 153 static int register_endpoint( ddf_fun_t *fun,154 usb_address_t address, usb_endpoint_t endpoint,148 static int register_endpoint( 149 ddf_fun_t *fun, usb_address_t address, usb_endpoint_t endpoint, 155 150 usb_transfer_type_t transfer_type, usb_direction_t direction, 156 151 size_t max_packet_size, unsigned int interval) … … 160 155 return ENOTSUP; 161 156 } 162 157 /*----------------------------------------------------------------------------*/ 163 158 /** Unregister endpoint (free some bandwidth reservation). 164 159 * … … 169 164 * @return Error code. 170 165 */ 171 static int unregister_endpoint(ddf_fun_t *fun, usb_address_t address, 166 static int unregister_endpoint( 167 ddf_fun_t *fun, usb_address_t address, 172 168 usb_endpoint_t endpoint, usb_direction_t direction) 173 169 { … … 194 190 * @return Error code. 195 191 */ 196 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 197 size_t max_packet_size, void *data, size_t size, 198 usbhc_iface_transfer_out_callback_t callback, void *arg) 199 { 200 hc_t *hc = fun_to_hc(fun); 201 assert(hc); 202 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address); 203 204 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 205 target.address, target.endpoint, size, max_packet_size); 206 207 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 208 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 209 &hc->manager); 210 if (!batch) 211 return ENOMEM; 212 batch_interrupt_out(batch); 213 const int ret = hc_schedule(hc, batch); 214 if (ret != EOK) { 215 batch_dispose(batch); 216 return ret; 217 } 218 return EOK; 192 static int interrupt_out( 193 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 194 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 195 { 196 assert(fun); 197 hc_t *hc = fun_to_hc(fun); 198 assert(hc); 199 usb_speed_t speed = 200 usb_device_keeper_get_speed(&hc->manager, target.address); 201 202 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 203 target.address, target.endpoint, size, max_packet_size); 204 205 usb_transfer_batch_t *batch = 206 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 207 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 208 if (!batch) 209 return ENOMEM; 210 batch_interrupt_out(batch); 211 const int ret = hc_schedule(hc, batch); 212 if (ret != EOK) { 213 batch_dispose(batch); 214 } 215 return ret; 219 216 } 220 217 /*----------------------------------------------------------------------------*/ … … 236 233 * @return Error code. 237 234 */ 238 static int interrupt_in( ddf_fun_t *fun, usb_target_t target,239 size_t max_packet_size, void *data, size_t size,240 usbhc_iface_transfer_in_callback_t callback, void *arg)241 { 242 243 244 245 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address); 246 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 247 target.address, target.endpoint, size, max_packet_size); 248 249 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT, 250 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 251 &hc->manager); 252 if (!batch) 253 return ENOMEM; 254 batch_interrupt_in(batch);255 const int ret = hc_schedule(hc,batch);256 if (ret != EOK) { 257 batch_dispose(batch); 258 return ret;259 260 return EOK;235 static int interrupt_in( 236 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 237 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 238 { 239 assert(fun); 240 hc_t *hc = fun_to_hc(fun); 241 assert(hc); 242 usb_speed_t speed = 243 usb_device_keeper_get_speed(&hc->manager, target.address); 244 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 245 target.address, target.endpoint, size, max_packet_size); 246 247 usb_transfer_batch_t *batch = 248 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 249 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 250 if (!batch) 251 return ENOMEM; 252 batch_interrupt_in(batch); 253 const int ret = hc_schedule(hc, batch); 254 if (ret != EOK) { 255 batch_dispose(batch); 256 } 257 return ret; 261 258 } 262 259 /*----------------------------------------------------------------------------*/ … … 278 275 * @return Error code. 279 276 */ 280 static int bulk_out(ddf_fun_t *fun, usb_target_t target, 281 size_t max_packet_size, void *data, size_t size, 282 usbhc_iface_transfer_out_callback_t callback, void *arg) 283 { 284 assert(fun); 285 hc_t *hc = fun_to_hc(fun); 286 assert(hc); 287 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address); 288 289 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 290 target.address, target.endpoint, size, max_packet_size); 291 292 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 293 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg, 294 &hc->manager); 295 if (!batch) 296 return ENOMEM; 297 batch_bulk_out(batch); 298 const int ret = hc_schedule(hc, batch); 299 if (ret != EOK) { 300 batch_dispose(batch); 301 return ret; 302 } 303 return EOK; 304 277 static int bulk_out( 278 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 279 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 280 { 281 assert(fun); 282 hc_t *hc = fun_to_hc(fun); 283 assert(hc); 284 usb_speed_t speed = 285 usb_device_keeper_get_speed(&hc->manager, target.address); 286 287 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 288 target.address, target.endpoint, size, max_packet_size); 289 290 usb_transfer_batch_t *batch = 291 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 292 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 293 if (!batch) 294 return ENOMEM; 295 batch_bulk_out(batch); 296 const int ret = hc_schedule(hc, batch); 297 if (ret != EOK) { 298 batch_dispose(batch); 299 } 300 return ret; 305 301 } 306 302 /*----------------------------------------------------------------------------*/ … … 322 318 * @return Error code. 323 319 */ 324 static int bulk_in( ddf_fun_t *fun, usb_target_t target,325 size_t max_packet_size, void *data, size_t size,326 usbhc_iface_transfer_in_callback_t callback, void *arg)327 { 328 329 330 331 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address); 332 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 333 target.address, target.endpoint, size, max_packet_size); 334 335 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK, 336 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg, 337 &hc->manager); 338 if (!batch) 339 return ENOMEM; 340 batch_bulk_in(batch);341 const int ret = hc_schedule(hc,batch);342 if (ret != EOK) { 343 batch_dispose(batch); 344 return ret;345 346 return EOK;320 static int bulk_in( 321 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 322 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 323 { 324 assert(fun); 325 hc_t *hc = fun_to_hc(fun); 326 assert(hc); 327 usb_speed_t speed = 328 usb_device_keeper_get_speed(&hc->manager, target.address); 329 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 330 target.address, target.endpoint, size, max_packet_size); 331 332 usb_transfer_batch_t *batch = 333 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 334 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 335 if (!batch) 336 return ENOMEM; 337 batch_bulk_in(batch); 338 const int ret = hc_schedule(hc, batch); 339 if (ret != EOK) { 340 batch_dispose(batch); 341 } 342 return ret; 347 343 } 348 344 /*----------------------------------------------------------------------------*/ … … 367 363 * @return Error code. 368 364 */ 369 static int control_write(ddf_fun_t *fun, usb_target_t target, 370 size_t max_packet_size, 371 void *setup_data, size_t setup_size, 372 void *data, size_t size, 365 static int control_write( 366 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, 367 void *setup_data, size_t setup_size, void *data, size_t size, 373 368 usbhc_iface_transfer_out_callback_t callback, void *arg) 374 369 { 375 assert(fun); 376 hc_t *hc = fun_to_hc(fun); 377 assert(hc); 378 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address); 379 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 380 speed, target.address, target.endpoint, size, max_packet_size); 381 382 if (setup_size != 8) 383 return EINVAL; 384 385 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 386 max_packet_size, speed, data, size, setup_data, setup_size, 387 NULL, callback, arg, &hc->manager); 388 if (!batch) 389 return ENOMEM; 390 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 391 batch_control_write(batch); 392 const int ret = hc_schedule(hc, batch); 393 if (ret != EOK) { 394 batch_dispose(batch); 395 return ret; 396 } 397 return EOK; 370 assert(fun); 371 hc_t *hc = fun_to_hc(fun); 372 assert(hc); 373 usb_speed_t speed = 374 usb_device_keeper_get_speed(&hc->manager, target.address); 375 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 376 speed, target.address, target.endpoint, size, max_packet_size); 377 378 if (setup_size != 8) 379 return EINVAL; 380 381 usb_transfer_batch_t *batch = 382 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 383 speed, data, size, setup_data, setup_size, NULL, callback, arg, 384 &hc->manager); 385 if (!batch) 386 return ENOMEM; 387 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 388 batch_control_write(batch); 389 const int ret = hc_schedule(hc, batch); 390 if (ret != EOK) { 391 batch_dispose(batch); 392 } 393 return ret; 398 394 } 399 395 /*----------------------------------------------------------------------------*/ … … 418 414 * @return Error code. 419 415 */ 420 static int control_read(ddf_fun_t *fun, usb_target_t target, 421 size_t max_packet_size, 422 void *setup_data, size_t setup_size, 423 void *data, size_t size, 416 static int control_read( 417 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, 418 void *setup_data, size_t setup_size, void *data, size_t size, 424 419 usbhc_iface_transfer_in_callback_t callback, void *arg) 425 420 { 426 assert(fun); 427 hc_t *hc = fun_to_hc(fun); 428 assert(hc); 429 usb_speed_t speed = usb_device_keeper_get_speed(&hc->manager, target.address); 430 431 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 432 speed, target.address, target.endpoint, size, max_packet_size); 433 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 434 max_packet_size, speed, data, size, setup_data, setup_size, callback, 435 NULL, arg, &hc->manager); 436 if (!batch) 437 return ENOMEM; 438 batch_control_read(batch); 439 const int ret = hc_schedule(hc, batch); 440 if (ret != EOK) { 441 batch_dispose(batch); 442 return ret; 443 } 444 return EOK; 421 assert(fun); 422 hc_t *hc = fun_to_hc(fun); 423 assert(hc); 424 usb_speed_t speed = 425 usb_device_keeper_get_speed(&hc->manager, target.address); 426 427 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 428 speed, target.address, target.endpoint, size, max_packet_size); 429 usb_transfer_batch_t *batch = 430 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, 431 speed, data, size, setup_data, setup_size, callback, NULL, arg, 432 &hc->manager); 433 if (!batch) 434 return ENOMEM; 435 batch_control_read(batch); 436 const int ret = hc_schedule(hc, batch); 437 if (ret != EOK) { 438 batch_dispose(batch); 439 } 440 return ret; 445 441 } 446 442 /*----------------------------------------------------------------------------*/ … … 463 459 464 460 .control_write = control_write, 465 .control_read = control_read 461 .control_read = control_read, 466 462 }; 467 463 -
uspace/drv/ohci/main.c
rd8421c4 rf97717d9 149 149 } 150 150 151 151 152 bool interrupts = false; 153 #ifdef CONFIG_USBHC_NO_INTERRUPTS 154 usb_log_warning("Interrupts disabled in OS config, " \ 155 "falling back to polling.\n"); 156 #else 152 157 ret = pci_enable_interrupts(device); 153 158 if (ret != EOK) { 154 usb_log_warning( 155 "Failed(%d) to enable interrupts, fall back to polling.\n", 156 ret); 159 usb_log_warning("Failed to enable interrupts: %s.\n", 160 str_error(ret)); 161 usb_log_info("HW interrupts not available, " \ 162 "falling back to polling.\n"); 157 163 } else { 158 164 usb_log_debug("Hw interrupts enabled.\n"); 159 165 interrupts = true; 160 166 } 167 #endif 161 168 162 169 ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts); … … 199 206 int main(int argc, char *argv[]) 200 207 { 201 usb_log_enable(USB_LOG_LEVEL_DE BUG, NAME);208 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 202 209 sleep(5); 203 210 return ddf_driver_main(&ohci_driver); -
uspace/drv/uhci-hcd/Makefile
rd8421c4 rf97717d9 37 37 transfer_list.c \ 38 38 uhci.c \ 39 uhci_hc.c \40 uhci_rh.c \41 uhci_struct/transfer_descriptor.c \39 hc.c \ 40 root_hub.c \ 41 hw_struct/transfer_descriptor.c \ 42 42 pci.c \ 43 43 batch.c -
uspace/drv/uhci-hcd/batch.c
rd8421c4 rf97717d9 40 40 #include "batch.h" 41 41 #include "transfer_list.h" 42 #include " uhci_hc.h"42 #include "hw_struct/transfer_descriptor.h" 43 43 #include "utils/malloc32.h" 44 #include "uhci_struct/transfer_descriptor.h"45 44 46 45 #define DEFAULT_ERROR_COUNT 3 … … 49 48 qh_t *qh; 50 49 td_t *tds; 51 size_t packets;50 size_t transfers; 52 51 usb_device_keeper_t *manager; 53 52 } uhci_batch_t; … … 65 64 * @param[in] target Device and endpoint target of the transaction. 66 65 * @param[in] transfer_type Interrupt, Control or Bulk. 67 * @param[in] max_packet_size maximum allowed size of data packets.66 * @param[in] max_packet_size maximum allowed size of data transfers. 68 67 * @param[in] speed Speed of the transaction. 69 68 * @param[in] buffer Data source/destination. … … 78 77 * NULL otherwise. 79 78 * 80 * Determines the number of needed packets (TDs). Prepares a transport buffer79 * Determines the number of needed transfers (TDs). Prepares a transport buffer 81 80 * (that is accessible by the hardware). Initializes parameters needed for the 82 81 * transaction and callback. … … 118 117 instance->private_data = data; 119 118 120 data-> packets = (buffer_size + max_packet_size - 1) / max_packet_size;119 data->transfers = (buffer_size + max_packet_size - 1) / max_packet_size; 121 120 if (transfer_type == USB_TRANSFER_CONTROL) { 122 data-> packets += 2;123 } 124 125 data->tds = malloc32(sizeof(td_t) * data-> packets);121 data->transfers += 2; 122 } 123 124 data->tds = malloc32(sizeof(td_t) * data->transfers); 126 125 CHECK_NULL_DISPOSE_RETURN( 127 126 data->tds, "Failed to allocate transfer descriptors.\n"); 128 bzero(data->tds, sizeof(td_t) * data-> packets);127 bzero(data->tds, sizeof(td_t) * data->transfers); 129 128 130 129 data->qh = malloc32(sizeof(qh_t)); … … 167 166 assert(data); 168 167 169 usb_log_debug2("Batch(%p) checking %d packet(s) for completion.\n",170 instance, data-> packets);168 usb_log_debug2("Batch(%p) checking %d transfer(s) for completion.\n", 169 instance, data->transfers); 171 170 instance->transfered_size = 0; 172 171 size_t i = 0; 173 for (;i < data-> packets; ++i) {172 for (;i < data->transfers; ++i) { 174 173 if (td_is_active(&data->tds[i])) { 175 174 return false; … … 299 298 * 300 299 * @param[in] instance Batch structure to use. 301 * @param[in] pid to use for data packets.300 * @param[in] pid Pid to use for data transfers. 302 301 * 303 302 * Packets with alternating toggle bit and supplied pid value. 304 * The last packetis marked with IOC flag.303 * The last transfer is marked with IOC flag. 305 304 */ 306 305 void batch_data(usb_transfer_batch_t *instance, usb_packet_id pid) … … 315 314 assert(toggle == 0 || toggle == 1); 316 315 317 size_t packet= 0;316 size_t transfer = 0; 318 317 size_t remain_size = instance->buffer_size; 319 318 while (remain_size > 0) { … … 326 325 remain_size : instance->max_packet_size; 327 326 328 td_t *next_ packet = (packet + 1 < data->packets)329 ? &data->tds[ packet+ 1] : NULL;330 331 assert( packet < data->packets);327 td_t *next_transfer = (transfer + 1 < data->transfers) 328 ? &data->tds[transfer + 1] : NULL; 329 330 assert(transfer < data->transfers); 332 331 assert(packet_size <= remain_size); 333 332 334 333 td_init( 335 &data->tds[ packet], DEFAULT_ERROR_COUNT, packet_size,334 &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size, 336 335 toggle, false, low_speed, instance->target, pid, trans_data, 337 next_ packet);336 next_transfer); 338 337 339 338 340 339 toggle = 1 - toggle; 341 340 remain_size -= packet_size; 342 ++ packet;343 } 344 td_set_ioc(&data->tds[ packet- 1]);341 ++transfer; 342 } 343 td_set_ioc(&data->tds[transfer - 1]); 345 344 usb_device_keeper_set_toggle(data->manager, instance->target, 346 345 instance->direction, toggle); … … 350 349 * 351 350 * @param[in] instance Batch structure to use. 352 * @param[in] data_stage to use for data packets.353 * @param[in] status_stage to use for data packets.351 * @param[in] data_stage Pid to use for data transfers. 352 * @param[in] status_stage Pid to use for data transfers. 354 353 * 355 354 * Setup stage with toggle 0 and USB_PID_SETUP. 356 355 * Data stage with alternating toggle and pid supplied by parameter. 357 356 * Status stage with toggle 1 and pid supplied by parameter. 358 * The last packetis marked with IOC.357 * The last transfer is marked with IOC. 359 358 */ 360 359 void batch_control(usb_transfer_batch_t *instance, … … 364 363 uhci_batch_t *data = instance->private_data; 365 364 assert(data); 366 assert(data-> packets >= 2);365 assert(data->transfers >= 2); 367 366 368 367 const bool low_speed = instance->speed == USB_SPEED_LOW; … … 375 374 376 375 /* data stage */ 377 size_t packet= 1;376 size_t transfer = 1; 378 377 size_t remain_size = instance->buffer_size; 379 378 while (remain_size > 0) { … … 389 388 390 389 td_init( 391 &data->tds[ packet], DEFAULT_ERROR_COUNT, packet_size,390 &data->tds[transfer], DEFAULT_ERROR_COUNT, packet_size, 392 391 toggle, false, low_speed, instance->target, data_stage, 393 control_data, &data->tds[ packet+ 1]);394 395 ++ packet;396 assert( packet < data->packets);392 control_data, &data->tds[transfer + 1]); 393 394 ++transfer; 395 assert(transfer < data->transfers); 397 396 assert(packet_size <= remain_size); 398 397 remain_size -= packet_size; … … 400 399 401 400 /* status stage */ 402 assert( packet == data->packets - 1);401 assert(transfer == data->transfers - 1); 403 402 404 403 td_init( 405 &data->tds[ packet], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed,404 &data->tds[transfer], DEFAULT_ERROR_COUNT, 0, 1, false, low_speed, 406 405 instance->target, status_stage, NULL, NULL); 407 td_set_ioc(&data->tds[ packet]);406 td_set_ioc(&data->tds[transfer]); 408 407 409 408 usb_log_debug2("Control last TD status: %x.\n", 410 data->tds[ packet].status);409 data->tds[transfer].status); 411 410 } 412 411 /*----------------------------------------------------------------------------*/ -
uspace/drv/uhci-hcd/batch.h
rd8421c4 rf97717d9 42 42 #include <usb/host/batch.h> 43 43 44 #include " uhci_struct/queue_head.h"44 #include "hw_struct/queue_head.h" 45 45 46 46 usb_transfer_batch_t * batch_get( -
uspace/drv/uhci-hcd/hc.c
rd8421c4 rf97717d9 42 42 #include <usb_iface.h> 43 43 44 #include " uhci_hc.h"44 #include "hc.h" 45 45 46 46 static irq_cmd_t uhci_cmds[] = { … … 60 60 }; 61 61 /*----------------------------------------------------------------------------*/ 62 static int uhci_hc_init_transfer_lists(uhci_hc_t *instance);63 static int uhci_hc_init_mem_structures(uhci_hc_t *instance);64 static void uhci_hc_init_hw(uhci_hc_t *instance);65 66 static int uhci_hc_interrupt_emulator(void *arg);67 static int uhci_hc_debug_checker(void *arg);68 69 static bool allowed_usb_packet(62 static int hc_init_transfer_lists(hc_t *instance); 63 static int hc_init_mem_structures(hc_t *instance); 64 static void hc_init_hw(hc_t *instance); 65 66 static int hc_interrupt_emulator(void *arg); 67 static int hc_debug_checker(void *arg); 68 69 static bool usb_is_allowed( 70 70 bool low_speed, usb_transfer_type_t transfer, size_t size); 71 71 /*----------------------------------------------------------------------------*/ … … 82 82 * interrupt fibrils. 83 83 */ 84 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun,84 int hc_init(hc_t *instance, ddf_fun_t *fun, 85 85 void *regs, size_t reg_size, bool interrupts) 86 86 { … … 112 112 io, reg_size); 113 113 114 ret = uhci_hc_init_mem_structures(instance);114 ret = hc_init_mem_structures(instance); 115 115 CHECK_RET_DEST_FUN_RETURN(ret, 116 116 "Failed to initialize UHCI memory structures.\n"); 117 117 118 uhci_hc_init_hw(instance);118 hc_init_hw(instance); 119 119 if (!interrupts) { 120 120 instance->cleaner = 121 fibril_create( uhci_hc_interrupt_emulator, instance);121 fibril_create(hc_interrupt_emulator, instance); 122 122 fibril_add_ready(instance->cleaner); 123 123 } else { … … 125 125 } 126 126 127 instance->debug_checker = fibril_create(uhci_hc_debug_checker, instance);128 fibril_add_ready(instance->debug_checker);129 130 usb_log_info("Started UHCI driver.\n"); 127 instance->debug_checker = 128 fibril_create(hc_debug_checker, instance); 129 // fibril_add_ready(instance->debug_checker); 130 131 131 return EOK; 132 132 #undef CHECK_RET_DEST_FUN_RETURN … … 138 138 * For magic values see UHCI Design Guide 139 139 */ 140 void uhci_hc_init_hw(uhci_hc_t *instance)140 void hc_init_hw(hc_t *instance) 141 141 { 142 142 assert(instance); … … 186 186 * - frame list page (needs to be one UHCI hw accessible 4K page) 187 187 */ 188 int uhci_hc_init_mem_structures(uhci_hc_t *instance)188 int hc_init_mem_structures(hc_t *instance) 189 189 { 190 190 assert(instance); … … 215 215 216 216 /* Init transfer lists */ 217 ret = uhci_hc_init_transfer_lists(instance);217 ret = hc_init_transfer_lists(instance); 218 218 CHECK_RET_DEST_CMDS_RETURN(ret, "Failed to init transfer lists.\n"); 219 219 usb_log_debug("Initialized transfer lists.\n"); … … 236 236 237 237 /* Init device keeper*/ 238 usb_device_keeper_init(&instance-> device_manager);238 usb_device_keeper_init(&instance->manager); 239 239 usb_log_debug("Initialized device manager.\n"); 240 240 … … 252 252 * USB scheduling. Sets pointer table for quick access. 253 253 */ 254 int uhci_hc_init_transfer_lists(uhci_hc_t *instance)254 int hc_init_transfer_lists(hc_t *instance) 255 255 { 256 256 assert(instance); … … 318 318 * Checks for bandwidth availability and appends the batch to the proper queue. 319 319 */ 320 int uhci_hc_schedule(uhci_hc_t *instance, usb_transfer_batch_t *batch)320 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch) 321 321 { 322 322 assert(instance); 323 323 assert(batch); 324 324 const int low_speed = (batch->speed == USB_SPEED_LOW); 325 if (! allowed_usb_packet(325 if (!usb_is_allowed( 326 326 low_speed, batch->transfer_type, batch->max_packet_size)) { 327 327 usb_log_warning( 328 "Invalid USB packetspecified %s SPEED %d %zu.\n",328 "Invalid USB transfer specified %s SPEED %d %zu.\n", 329 329 low_speed ? "LOW" : "FULL" , batch->transfer_type, 330 330 batch->max_packet_size); … … 351 351 * - resume from suspend state (not implemented) 352 352 */ 353 void uhci_hc_interrupt(uhci_hc_t *instance, uint16_t status)353 void hc_interrupt(hc_t *instance, uint16_t status) 354 354 { 355 355 assert(instance); … … 373 373 if (instance->hw_failures < UHCI_ALLOWED_HW_FAIL) { 374 374 /* reinitialize hw, this triggers virtual disconnect*/ 375 uhci_hc_init_hw(instance);375 hc_init_hw(instance); 376 376 } else { 377 377 usb_log_fatal("Too many UHCI hardware failures!.\n"); 378 uhci_hc_fini(instance);378 hc_fini(instance); 379 379 } 380 380 } … … 386 386 * @return EOK (should never return) 387 387 */ 388 int uhci_hc_interrupt_emulator(void* arg)388 int hc_interrupt_emulator(void* arg) 389 389 { 390 390 usb_log_debug("Started interrupt emulator.\n"); 391 uhci_hc_t *instance = (uhci_hc_t*)arg;391 hc_t *instance = (hc_t*)arg; 392 392 assert(instance); 393 393 … … 398 398 if (status != 0) 399 399 usb_log_debug2("UHCI status: %x.\n", status); 400 uhci_hc_interrupt(instance, status);400 hc_interrupt(instance, status); 401 401 async_usleep(UHCI_CLEANER_TIMEOUT); 402 402 } … … 409 409 * @return EOK (should never return) 410 410 */ 411 int uhci_hc_debug_checker(void *arg)412 { 413 uhci_hc_t *instance = (uhci_hc_t*)arg;411 int hc_debug_checker(void *arg) 412 { 413 hc_t *instance = (hc_t*)arg; 414 414 assert(instance); 415 415 … … 471 471 } 472 472 /*----------------------------------------------------------------------------*/ 473 /** Check transfer packets,for USB validity473 /** Check transfers for USB validity 474 474 * 475 475 * @param[in] low_speed Transfer speed. 476 476 * @param[in] transfer Transer type 477 * @param[in] size Maximum size of usedpackets477 * @param[in] size Size of data packets 478 478 * @return True if transaction is allowed by USB specs, false otherwise 479 479 */ 480 bool allowed_usb_packet(480 bool usb_is_allowed( 481 481 bool low_speed, usb_transfer_type_t transfer, size_t size) 482 482 { -
uspace/drv/uhci-hcd/hc.h
rd8421c4 rf97717d9 82 82 #define UHCI_ALLOWED_HW_FAIL 5 83 83 84 typedef struct uhci_hc {85 usb_device_keeper_t device_manager;84 typedef struct hc { 85 usb_device_keeper_t manager; 86 86 87 87 regs_t *registers; … … 104 104 105 105 ddf_fun_t *ddf_instance; 106 } uhci_hc_t;106 } hc_t; 107 107 108 int uhci_hc_init(uhci_hc_t *instance, ddf_fun_t *fun,108 int hc_init(hc_t *instance, ddf_fun_t *fun, 109 109 void *regs, size_t reg_size, bool interupts); 110 110 111 int uhci_hc_schedule(uhci_hc_t *instance, usb_transfer_batch_t *batch);111 int hc_schedule(hc_t *instance, usb_transfer_batch_t *batch); 112 112 113 void uhci_hc_interrupt(uhci_hc_t *instance, uint16_t status);113 void hc_interrupt(hc_t *instance, uint16_t status); 114 114 115 115 /** Safely dispose host controller internal structures … … 117 117 * @param[in] instance Host controller structure to use. 118 118 */ 119 static inline void uhci_hc_fini(uhci_hc_t *instance) { /* TODO: implement*/ };119 static inline void hc_fini(hc_t *instance) { /* TODO: implement*/ }; 120 120 121 121 /** Get and cast pointer to the driver data … … 124 124 * @return cast pointer to driver_data 125 125 */ 126 static inline uhci_hc_t * fun_to_uhci_hc(ddf_fun_t *fun)127 { return ( uhci_hc_t*)fun->driver_data; }126 static inline hc_t * fun_to_hc(ddf_fun_t *fun) 127 { return (hc_t*)fun->driver_data; } 128 128 #endif 129 129 /** -
uspace/drv/uhci-hcd/hw_struct/link_pointer.h
rd8421c4 rf97717d9 49 49 ((address & LINK_POINTER_ADDRESS_MASK) | LINK_POINTER_QUEUE_HEAD_FLAG) 50 50 51 #define LINK_POINTER_TD(address) \ 52 (address & LINK_POINTER_ADDRESS_MASK) 53 54 #define LINK_POINTER_TERM \ 55 ((link_pointer_t)LINK_POINTER_TERMINATE_FLAG) 56 51 57 #endif 52 58 /** -
uspace/drv/uhci-hcd/hw_struct/queue_head.h
rd8421c4 rf97717d9 72 72 /* Address is valid and not terminal */ 73 73 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 74 instance->next = (pa & LINK_POINTER_ADDRESS_MASK) 75 | LINK_POINTER_QUEUE_HEAD_FLAG; 74 instance->next = LINK_POINTER_QH(pa); 76 75 } else { 77 instance->next = 0 | LINK_POINTER_TERMINATE_FLAG;76 instance->next = LINK_POINTER_TERM; 78 77 } 79 78 } … … 91 90 /* Address is valid and not terminal */ 92 91 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 93 instance->element = (pa & LINK_POINTER_ADDRESS_MASK) 94 | LINK_POINTER_QUEUE_HEAD_FLAG; 92 instance->element = LINK_POINTER_QH(pa); 95 93 } else { 96 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;94 instance->element = LINK_POINTER_TERM; 97 95 } 98 96 } … … 109 107 { 110 108 if (pa && ((pa & LINK_POINTER_TERMINATE_FLAG) == 0)) { 111 instance->element = (pa & LINK_POINTER_ADDRESS_MASK);109 instance->element = LINK_POINTER_TD(pa); 112 110 } else { 113 instance->element = 0 | LINK_POINTER_TERMINATE_FLAG;111 instance->element = LINK_POINTER_TERM; 114 112 } 115 113 } -
uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.c
rd8421c4 rf97717d9 69 69 || (pid == USB_PID_OUT)); 70 70 71 const uint32_t next_pa = addr_to_phys(next); 72 assert((next_pa & LINK_POINTER_ADDRESS_MASK) == next_pa); 73 71 74 instance->next = 0 72 75 | LINK_POINTER_VERTICAL_FLAG 73 | ( (next != NULL) ? addr_to_phys(next): LINK_POINTER_TERMINATE_FLAG);76 | (next_pa ? next_pa : LINK_POINTER_TERMINATE_FLAG); 74 77 75 78 instance->status = 0 … … 90 93 | ((pid & TD_DEVICE_PID_MASK) << TD_DEVICE_PID_POS); 91 94 92 instance->buffer_ptr = 0; 93 94 if (size) { 95 instance->buffer_ptr = (uintptr_t)addr_to_phys(buffer); 96 } 95 instance->buffer_ptr = addr_to_phys(buffer); 97 96 98 97 usb_log_debug2("Created TD(%p): %X:%X:%X:%X(%p).\n", … … 115 114 assert(instance); 116 115 117 if ((instance->status & TD_STATUS_ERROR_STALLED) != 0) 118 return ESTALL; 116 /* this is hc internal error it should never be reported */ 117 if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0) 118 return EAGAIN; 119 119 120 /* CRC or timeout error, like device not present or bad data, 121 * it won't be reported unless err count reached zero */ 120 122 if ((instance->status & TD_STATUS_ERROR_CRC) != 0) 121 123 return EBADCHECKSUM; 122 124 123 if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0) 125 /* hc does not end transaction on these, it should never be reported */ 126 if ((instance->status & TD_STATUS_ERROR_NAK) != 0) 124 127 return EAGAIN; 125 128 129 /* buffer overrun or underrun */ 130 if ((instance->status & TD_STATUS_ERROR_BUFFER) != 0) 131 return ERANGE; 132 133 /* device babble is something serious */ 126 134 if ((instance->status & TD_STATUS_ERROR_BABBLE) != 0) 127 135 return EIO; 128 136 129 if ((instance->status & TD_STATUS_ERROR_NAK) != 0) 130 return EAGAIN; 131 132 if ((instance->status & TD_STATUS_ERROR_BIT_STUFF) != 0) 133 return EAGAIN; 137 /* stall might represent err count reaching zero or stall response from 138 * the device, is err count reached zero, one of the above is reported*/ 139 if ((instance->status & TD_STATUS_ERROR_STALLED) != 0) 140 return ESTALL; 134 141 135 142 return EOK; -
uspace/drv/uhci-hcd/hw_struct/transfer_descriptor.h
rd8421c4 rf97717d9 108 108 } 109 109 /*----------------------------------------------------------------------------*/ 110 /** Check whether less than max data were rec ieved and packet is marked as SPD.110 /** Check whether less than max data were received on SPD marked transfer. 111 111 * 112 112 * @param[in] instance TD structure to use. 113 * @return True if packet is short (less than max bytes and SPD set), false114 * 113 * @return True if data packet is short (less than max bytes and SPD set), 114 * false otherwise. 115 115 */ 116 116 static inline bool td_is_short(td_t *instance) -
uspace/drv/uhci-hcd/iface.c
rd8421c4 rf97717d9 33 33 */ 34 34 #include <ddf/driver.h> 35 #include < remote_usbhc.h>35 #include <errno.h> 36 36 37 37 #include <usb/debug.h> 38 38 39 #include <errno.h>40 41 39 #include "iface.h" 42 #include " uhci_hc.h"40 #include "hc.h" 43 41 44 42 /** Reserve default address interface function … … 48 46 * @return Error code. 49 47 */ 50 /*----------------------------------------------------------------------------*/51 48 static int reserve_default_address(ddf_fun_t *fun, usb_speed_t speed) 52 49 { 53 50 assert(fun); 54 uhci_hc_t *hc = fun_to_uhci_hc(fun);51 hc_t *hc = fun_to_hc(fun); 55 52 assert(hc); 56 53 usb_log_debug("Default address request with speed %d.\n", speed); 57 usb_device_keeper_reserve_default_address(&hc-> device_manager, speed);54 usb_device_keeper_reserve_default_address(&hc->manager, speed); 58 55 return EOK; 59 56 } … … 67 64 { 68 65 assert(fun); 69 uhci_hc_t *hc = fun_to_uhci_hc(fun);66 hc_t *hc = fun_to_hc(fun); 70 67 assert(hc); 71 68 usb_log_debug("Default address release.\n"); 72 usb_device_keeper_release_default_address(&hc-> device_manager);69 usb_device_keeper_release_default_address(&hc->manager); 73 70 return EOK; 74 71 } … … 81 78 * @return Error code. 82 79 */ 83 static int request_address( ddf_fun_t *fun, usb_speed_t speed,84 usb_address_t *address)85 { 86 assert(fun); 87 uhci_hc_t *hc = fun_to_uhci_hc(fun);80 static int request_address( 81 ddf_fun_t *fun, usb_speed_t speed, usb_address_t *address) 82 { 83 assert(fun); 84 hc_t *hc = fun_to_hc(fun); 88 85 assert(hc); 89 86 assert(address); 90 87 91 88 usb_log_debug("Address request with speed %d.\n", speed); 92 *address = device_keeper_get_free_address(&hc-> device_manager, speed);89 *address = device_keeper_get_free_address(&hc->manager, speed); 93 90 usb_log_debug("Address request with result: %d.\n", *address); 94 91 if (*address <= 0) 95 92 return *address; 96 93 return EOK; 97 94 } … … 108 105 { 109 106 assert(fun); 110 uhci_hc_t *hc = fun_to_uhci_hc(fun);107 hc_t *hc = fun_to_hc(fun); 111 108 assert(hc); 112 109 usb_log_debug("Address bind %d-%d.\n", address, handle); 113 usb_device_keeper_bind(&hc-> device_manager, address, handle);110 usb_device_keeper_bind(&hc->manager, address, handle); 114 111 return EOK; 115 112 } … … 124 121 { 125 122 assert(fun); 126 uhci_hc_t *hc = fun_to_uhci_hc(fun);123 hc_t *hc = fun_to_hc(fun); 127 124 assert(hc); 128 125 usb_log_debug("Address release %d.\n", address); 129 usb_device_keeper_release(&hc-> device_manager, address);126 usb_device_keeper_release(&hc->manager, address); 130 127 return EOK; 131 128 } … … 142 139 * @return Error code. 143 140 */ 144 static int interrupt_out(ddf_fun_t *fun, usb_target_t target, 145 size_t max_packet_size, void *data, size_t size, 146 usbhc_iface_transfer_out_callback_t callback, void *arg) 147 { 148 assert(fun); 149 uhci_hc_t *hc = fun_to_uhci_hc(fun); 150 assert(hc); 151 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 141 static int interrupt_out( 142 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 143 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 144 { 145 assert(fun); 146 hc_t *hc = fun_to_hc(fun); 147 assert(hc); 148 usb_speed_t speed = 149 usb_device_keeper_get_speed(&hc->manager, target.address); 152 150 153 151 usb_log_debug("Interrupt OUT %d:%d %zu(%zu).\n", 154 152 target.address, target.endpoint, size, max_packet_size); 155 153 156 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,157 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,158 &hc->device_manager);154 usb_transfer_batch_t *batch = 155 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 156 speed, data, size, NULL, 0, NULL, callback, arg, &hc->manager); 159 157 if (!batch) 160 158 return ENOMEM; 161 159 batch_interrupt_out(batch); 162 const int ret = uhci_hc_schedule(hc, batch); 163 if (ret != EOK) { 164 batch_dispose(batch); 165 return ret; 166 } 167 return EOK; 160 const int ret = hc_schedule(hc, batch); 161 if (ret != EOK) { 162 batch_dispose(batch); 163 } 164 return ret; 168 165 } 169 166 /*----------------------------------------------------------------------------*/ … … 179 176 * @return Error code. 180 177 */ 181 static int interrupt_in(ddf_fun_t *fun, usb_target_t target, 182 size_t max_packet_size, void *data, size_t size, 183 usbhc_iface_transfer_in_callback_t callback, void *arg) 184 { 185 assert(fun); 186 uhci_hc_t *hc = fun_to_uhci_hc(fun); 187 assert(hc); 188 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 178 static int interrupt_in( 179 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 180 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 181 { 182 assert(fun); 183 hc_t *hc = fun_to_hc(fun); 184 assert(hc); 185 usb_speed_t speed = 186 usb_device_keeper_get_speed(&hc->manager, target.address); 189 187 usb_log_debug("Interrupt IN %d:%d %zu(%zu).\n", 190 188 target.address, target.endpoint, size, max_packet_size); 191 189 192 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_INTERRUPT,193 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,194 &hc->device_manager);190 usb_transfer_batch_t *batch = 191 batch_get(fun, target, USB_TRANSFER_INTERRUPT, max_packet_size, 192 speed, data, size, NULL, 0, callback, NULL, arg, &hc->manager); 195 193 if (!batch) 196 194 return ENOMEM; 197 195 batch_interrupt_in(batch); 198 const int ret = uhci_hc_schedule(hc, batch); 199 if (ret != EOK) { 200 batch_dispose(batch); 201 return ret; 202 } 203 return EOK; 196 const int ret = hc_schedule(hc, batch); 197 if (ret != EOK) { 198 batch_dispose(batch); 199 } 200 return ret; 204 201 } 205 202 /*----------------------------------------------------------------------------*/ … … 215 212 * @return Error code. 216 213 */ 217 static int bulk_out(ddf_fun_t *fun, usb_target_t target, 218 size_t max_packet_size, void *data, size_t size, 219 usbhc_iface_transfer_out_callback_t callback, void *arg) 220 { 221 assert(fun); 222 uhci_hc_t *hc = fun_to_uhci_hc(fun); 223 assert(hc); 224 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 214 static int bulk_out( 215 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 216 size_t size, usbhc_iface_transfer_out_callback_t callback, void *arg) 217 { 218 assert(fun); 219 hc_t *hc = fun_to_hc(fun); 220 assert(hc); 221 usb_speed_t speed = 222 usb_device_keeper_get_speed(&hc->manager, target.address); 225 223 226 224 usb_log_debug("Bulk OUT %d:%d %zu(%zu).\n", 227 225 target.address, target.endpoint, size, max_packet_size); 228 226 229 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,230 max_packet_size, speed, data, size, NULL, 0, NULL, callback, arg,231 &hc->device_manager);227 usb_transfer_batch_t *batch = 228 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 229 data, size, NULL, 0, NULL, callback, arg, &hc->manager); 232 230 if (!batch) 233 231 return ENOMEM; 234 232 batch_bulk_out(batch); 235 const int ret = uhci_hc_schedule(hc, batch); 236 if (ret != EOK) { 237 batch_dispose(batch); 238 return ret; 239 } 240 return EOK; 233 const int ret = hc_schedule(hc, batch); 234 if (ret != EOK) { 235 batch_dispose(batch); 236 } 237 return ret; 241 238 } 242 239 /*----------------------------------------------------------------------------*/ … … 252 249 * @return Error code. 253 250 */ 254 static int bulk_in(ddf_fun_t *fun, usb_target_t target, 255 size_t max_packet_size, void *data, size_t size, 256 usbhc_iface_transfer_in_callback_t callback, void *arg) 257 { 258 assert(fun); 259 uhci_hc_t *hc = fun_to_uhci_hc(fun); 260 assert(hc); 261 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 251 static int bulk_in( 252 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, void *data, 253 size_t size, usbhc_iface_transfer_in_callback_t callback, void *arg) 254 { 255 assert(fun); 256 hc_t *hc = fun_to_hc(fun); 257 assert(hc); 258 usb_speed_t speed = 259 usb_device_keeper_get_speed(&hc->manager, target.address); 262 260 usb_log_debug("Bulk IN %d:%d %zu(%zu).\n", 263 261 target.address, target.endpoint, size, max_packet_size); 264 262 265 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_BULK,266 max_packet_size, speed, data, size, NULL, 0, callback, NULL, arg,267 &hc->device_manager);263 usb_transfer_batch_t *batch = 264 batch_get(fun, target, USB_TRANSFER_BULK, max_packet_size, speed, 265 data, size, NULL, 0, callback, NULL, arg, &hc->manager); 268 266 if (!batch) 269 267 return ENOMEM; 270 268 batch_bulk_in(batch); 271 const int ret = uhci_hc_schedule(hc, batch); 272 if (ret != EOK) { 273 batch_dispose(batch); 274 return ret; 275 } 276 return EOK; 269 const int ret = hc_schedule(hc, batch); 270 if (ret != EOK) { 271 batch_dispose(batch); 272 } 273 return ret; 277 274 } 278 275 /*----------------------------------------------------------------------------*/ … … 282 279 * @param[in] target USB device to write to. 283 280 * @param[in] max_packet_size maximum size of data packet the device accepts. 284 * @param[in] setup_data Data to send with SETUP packet.285 * @param[in] setup_size Size of data to send with SETUP packet (should be8B).281 * @param[in] setup_data Data to send with SETUP transfer. 282 * @param[in] setup_size Size of data to send with SETUP transfer (always 8B). 286 283 * @param[in] data Source of data. 287 284 * @param[in] size Size of data source. … … 290 287 * @return Error code. 291 288 */ 292 static int control_write( ddf_fun_t *fun, usb_target_t target,293 size_t max_packet_size,289 static int control_write( 290 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, 294 291 void *setup_data, size_t setup_size, void *data, size_t size, 295 292 usbhc_iface_transfer_out_callback_t callback, void *arg) 296 293 { 297 294 assert(fun); 298 uhci_hc_t *hc = fun_to_uhci_hc(fun); 299 assert(hc); 300 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 295 hc_t *hc = fun_to_hc(fun); 296 assert(hc); 297 usb_speed_t speed = 298 usb_device_keeper_get_speed(&hc->manager, target.address); 301 299 usb_log_debug("Control WRITE (%d) %d:%d %zu(%zu).\n", 302 300 speed, target.address, target.endpoint, size, max_packet_size); … … 305 303 return EINVAL; 306 304 307 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 308 max_packet_size, speed, data, size, setup_data, setup_size, 309 NULL, callback, arg, &hc->device_manager); 310 if (!batch) 311 return ENOMEM; 312 usb_device_keeper_reset_if_need(&hc->device_manager, target, setup_data); 305 usb_transfer_batch_t *batch = 306 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 307 data, size, setup_data, setup_size, NULL, callback, arg, 308 &hc->manager); 309 if (!batch) 310 return ENOMEM; 311 usb_device_keeper_reset_if_need(&hc->manager, target, setup_data); 313 312 batch_control_write(batch); 314 const int ret = uhci_hc_schedule(hc, batch); 315 if (ret != EOK) { 316 batch_dispose(batch); 317 return ret; 318 } 319 return EOK; 313 const int ret = hc_schedule(hc, batch); 314 if (ret != EOK) { 315 batch_dispose(batch); 316 } 317 return ret; 320 318 } 321 319 /*----------------------------------------------------------------------------*/ … … 333 331 * @return Error code. 334 332 */ 335 static int control_read( ddf_fun_t *fun, usb_target_t target,336 size_t max_packet_size,333 static int control_read( 334 ddf_fun_t *fun, usb_target_t target, size_t max_packet_size, 337 335 void *setup_data, size_t setup_size, void *data, size_t size, 338 336 usbhc_iface_transfer_in_callback_t callback, void *arg) 339 337 { 340 338 assert(fun); 341 uhci_hc_t *hc = fun_to_uhci_hc(fun); 342 assert(hc); 343 usb_speed_t speed = usb_device_keeper_get_speed(&hc->device_manager, target.address); 339 hc_t *hc = fun_to_hc(fun); 340 assert(hc); 341 usb_speed_t speed = 342 usb_device_keeper_get_speed(&hc->manager, target.address); 344 343 345 344 usb_log_debug("Control READ(%d) %d:%d %zu(%zu).\n", 346 345 speed, target.address, target.endpoint, size, max_packet_size); 347 usb_transfer_batch_t *batch = batch_get(fun, target, USB_TRANSFER_CONTROL, 348 max_packet_size, speed, data, size, setup_data, setup_size, callback, 349 NULL, arg, &hc->device_manager); 346 usb_transfer_batch_t *batch = 347 batch_get(fun, target, USB_TRANSFER_CONTROL, max_packet_size, speed, 348 data, size, setup_data, setup_size, callback, NULL, arg, 349 &hc->manager); 350 350 if (!batch) 351 351 return ENOMEM; 352 352 batch_control_read(batch); 353 const int ret = uhci_hc_schedule(hc, batch); 354 if (ret != EOK) { 355 batch_dispose(batch); 356 return ret; 357 } 358 return EOK; 359 } 360 /*----------------------------------------------------------------------------*/ 361 usbhc_iface_t uhci_hc_iface = { 353 const int ret = hc_schedule(hc, batch); 354 if (ret != EOK) { 355 batch_dispose(batch); 356 } 357 return ret; 358 } 359 /*----------------------------------------------------------------------------*/ 360 usbhc_iface_t hc_iface = { 362 361 .reserve_default_address = reserve_default_address, 363 362 .release_default_address = release_default_address, … … 369 368 .interrupt_in = interrupt_in, 370 369 370 .bulk_out = bulk_out, 371 371 .bulk_in = bulk_in, 372 .bulk_out = bulk_out, 373 372 373 .control_write = control_write, 374 374 .control_read = control_read, 375 .control_write = control_write,376 375 }; 377 376 /** -
uspace/drv/uhci-hcd/iface.h
rd8421c4 rf97717d9 38 38 #include <usbhc_iface.h> 39 39 40 extern usbhc_iface_t uhci_hc_iface;40 extern usbhc_iface_t hc_iface; 41 41 42 42 #endif -
uspace/drv/uhci-hcd/main.c
rd8421c4 rf97717d9 62 62 int uhci_add_device(ddf_dev_t *device) 63 63 { 64 usb_log_ info("uhci_add_device() called\n");64 usb_log_debug("uhci_add_device() called\n"); 65 65 assert(device); 66 66 uhci_t *uhci = malloc(sizeof(uhci_t)); … … 72 72 int ret = uhci_init(uhci, device); 73 73 if (ret != EOK) { 74 usb_log_error("Failed to initialzie UHCI driver.\n"); 74 usb_log_error("Failed to initialize UHCI driver: %s.\n", 75 str_error(ret)); 75 76 return ret; 76 77 } 77 78 device->driver_data = uhci; 79 80 usb_log_info("Controlling new UHCI device `%s'.\n", device->name); 81 78 82 return EOK; 79 83 } … … 89 93 int main(int argc, char *argv[]) 90 94 { 95 printf(NAME ": HelenOS UHCI driver.\n"); 96 91 97 sleep(3); /* TODO: remove in final version */ 92 usb_log_enable(USB_LOG_LEVEL_DE BUG, NAME);98 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 93 99 94 100 return ddf_driver_main(&uhci_driver); -
uspace/drv/uhci-hcd/root_hub.c
rd8421c4 rf97717d9 39 39 #include <usb/debug.h> 40 40 41 #include "uhci_rh.h" 42 #include "uhci_hc.h" 41 #include "root_hub.h" 43 42 44 43 /** Root hub initialization … … 49 48 * @return Error code. 50 49 */ 51 int uhci_rh_init(52 uhci_rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size)50 int rh_init( 51 rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size) 53 52 { 54 53 assert(fun); -
uspace/drv/uhci-hcd/root_hub.h
rd8421c4 rf97717d9 39 39 #include <ops/hw_res.h> 40 40 41 typedef struct uhci_rh {41 typedef struct rh { 42 42 hw_resource_list_t resource_list; 43 43 hw_resource_t io_regs; 44 } uhci_rh_t;44 } rh_t; 45 45 46 int uhci_rh_init(47 uhci_rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size);46 int rh_init( 47 rh_t *instance, ddf_fun_t *fun, uintptr_t reg_addr, size_t reg_size); 48 48 49 49 #endif -
uspace/drv/uhci-hcd/transfer_list.c
rd8421c4 rf97717d9 79 79 if (!instance->queue_head) 80 80 return; 81 /* Set both next and element to point to the same QH*/81 /* Set both queue_head.next to point to the follower */ 82 82 qh_set_next_qh(instance->queue_head, next->queue_head_pa); 83 qh_set_element_qh(instance->queue_head, next->queue_head_pa);84 83 } 85 84 /*----------------------------------------------------------------------------*/ … … 92 91 * The batch is added to the end of the list and queue. 93 92 */ 94 void transfer_list_add_batch(transfer_list_t *instance, usb_transfer_batch_t *batch) 93 void transfer_list_add_batch( 94 transfer_list_t *instance, usb_transfer_batch_t *batch) 95 95 { 96 96 assert(instance); … … 98 98 usb_log_debug2("Queue %s: Adding batch(%p).\n", instance->name, batch); 99 99 100 const uint32_t pa = addr_to_phys(batch_qh(batch));101 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa);102 103 /* New batch will be added to the end of the current list104 * so set the link accordingly */105 qh_set_next_qh(batch_qh(batch), instance->queue_head->next);106 107 100 fibril_mutex_lock(&instance->guard); 108 101 102 qh_t *last_qh = NULL; 109 103 /* Add to the hardware queue. */ 110 104 if (list_empty(&instance->batch_list)) { 111 105 /* There is nothing scheduled */ 112 qh_t *qh = instance->queue_head; 113 assert(qh->element == qh->next); 114 qh_set_element_qh(qh, pa); 106 last_qh = instance->queue_head; 115 107 } else { 116 108 /* There is something scheduled */ 117 109 usb_transfer_batch_t *last = list_get_instance( 118 110 instance->batch_list.prev, usb_transfer_batch_t, link); 119 qh_set_next_qh(batch_qh(last), pa); 120 } 111 last_qh = batch_qh(last); 112 } 113 const uint32_t pa = addr_to_phys(batch_qh(batch)); 114 assert((pa & LINK_POINTER_ADDRESS_MASK) == pa); 115 116 /* keep link */ 117 batch_qh(batch)->next = last_qh->next; 118 qh_set_next_qh(last_qh, pa); 119 121 120 /* Add to the driver list */ 122 121 list_append(&batch->link, &instance->batch_list); … … 148 147 while (current != &instance->batch_list) { 149 148 link_t *next = current->next; 150 usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link); 149 usb_transfer_batch_t *batch = 150 list_get_instance(current, usb_transfer_batch_t, link); 151 151 152 152 if (batch_is_complete(batch)) { … … 162 162 link_t *item = done.next; 163 163 list_remove(item); 164 usb_transfer_batch_t *batch = list_get_instance(item, usb_transfer_batch_t, link); 164 usb_transfer_batch_t *batch = 165 list_get_instance(item, usb_transfer_batch_t, link); 165 166 batch->next_step(batch); 166 167 } … … 174 175 { 175 176 fibril_mutex_lock(&instance->guard); 176 while ( list_empty(&instance->batch_list)) {177 while (!list_empty(&instance->batch_list)) { 177 178 link_t *current = instance->batch_list.next; 178 usb_transfer_batch_t *batch = list_get_instance(current, usb_transfer_batch_t, link); 179 usb_transfer_batch_t *batch = 180 list_get_instance(current, usb_transfer_batch_t, link); 179 181 transfer_list_remove_batch(instance, batch); 180 182 usb_transfer_batch_finish(batch, EIO); … … 191 193 * Does not lock the transfer list, caller is responsible for that. 192 194 */ 193 void transfer_list_remove_batch(transfer_list_t *instance, usb_transfer_batch_t *batch) 195 void transfer_list_remove_batch( 196 transfer_list_t *instance, usb_transfer_batch_t *batch) 194 197 { 195 198 assert(instance); … … 197 200 assert(batch); 198 201 assert(batch_qh(batch)); 202 assert(fibril_mutex_is_locked(&instance->guard)); 203 199 204 usb_log_debug2( 200 205 "Queue %s: removing batch(%p).\n", instance->name, batch); 201 206 202 const char * 207 const char *qpos = NULL; 203 208 /* Remove from the hardware queue */ 204 if ( batch->link.prev == &instance->batch_list) {209 if (instance->batch_list.next == &batch->link) { 205 210 /* I'm the first one here */ 206 qh_set_element_qh(instance->queue_head, batch_qh(batch)->next); 207 pos = "FIRST"; 211 assert((instance->queue_head->next & LINK_POINTER_ADDRESS_MASK) 212 == addr_to_phys(batch_qh(batch))); 213 instance->queue_head->next = batch_qh(batch)->next; 214 qpos = "FIRST"; 208 215 } else { 209 216 usb_transfer_batch_t *prev = 210 list_get_instance(batch->link.prev, usb_transfer_batch_t, link); 211 qh_set_next_qh(batch_qh(prev), batch_qh(batch)->next); 212 pos = "NOT FIRST"; 213 } 214 /* Remove from the driver list */ 217 list_get_instance( 218 batch->link.prev, usb_transfer_batch_t, link); 219 assert((batch_qh(prev)->next & LINK_POINTER_ADDRESS_MASK) 220 == addr_to_phys(batch_qh(batch))); 221 batch_qh(prev)->next = batch_qh(batch)->next; 222 qpos = "NOT FIRST"; 223 } 224 /* Remove from the batch list */ 215 225 list_remove(&batch->link); 216 usb_log_debug("Batch(%p) removed (%s) from %s, next element%x.\n",217 batch, pos, instance->name, batch_qh(batch)->next);226 usb_log_debug("Batch(%p) removed (%s) from %s, next %x.\n", 227 batch, qpos, instance->name, batch_qh(batch)->next); 218 228 } 219 229 /** -
uspace/drv/uhci-hcd/transfer_list.h
rd8421c4 rf97717d9 37 37 #include <fibril_synch.h> 38 38 39 #include "uhci_struct/queue_head.h"40 41 39 #include "batch.h" 40 #include "hw_struct/queue_head.h" 42 41 43 42 typedef struct transfer_list -
uspace/drv/uhci-hcd/uhci.c
rd8421c4 rf97717d9 54 54 { 55 55 assert(dev); 56 uhci_hc_t *hc = &((uhci_t*)dev->driver_data)->hc;56 hc_t *hc = &((uhci_t*)dev->driver_data)->hc; 57 57 uint16_t status = IPC_GET_ARG1(*call); 58 58 assert(hc); 59 uhci_hc_interrupt(hc, status);59 hc_interrupt(hc, status); 60 60 } 61 61 /*----------------------------------------------------------------------------*/ … … 70 70 { 71 71 assert(fun); 72 usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc. device_manager;72 usb_device_keeper_t *manager = &((uhci_t*)fun->dev->driver_data)->hc.manager; 73 73 74 74 usb_address_t addr = usb_device_keeper_find(manager, handle); … … 107 107 }; 108 108 /*----------------------------------------------------------------------------*/ 109 static ddf_dev_ops_t uhci_hc_ops = {109 static ddf_dev_ops_t hc_ops = { 110 110 .interfaces[USB_DEV_IFACE] = &usb_iface, 111 .interfaces[USBHC_DEV_IFACE] = & uhci_hc_iface, /* see iface.h/c */111 .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */ 112 112 }; 113 113 /*----------------------------------------------------------------------------*/ … … 120 120 { 121 121 assert(fun); 122 return &(( uhci_rh_t*)fun->driver_data)->resource_list;122 return &((rh_t*)fun->driver_data)->resource_list; 123 123 } 124 124 /*----------------------------------------------------------------------------*/ … … 128 128 }; 129 129 /*----------------------------------------------------------------------------*/ 130 static ddf_dev_ops_t uhci_rh_ops = {130 static ddf_dev_ops_t rh_ops = { 131 131 .interfaces[USB_DEV_IFACE] = &usb_iface, 132 132 .interfaces[HW_RES_DEV_IFACE] = &hw_res_iface … … 167 167 CHECK_RET_DEST_FUN_RETURN(ret, 168 168 "Failed(%d) to get I/O addresses:.\n", ret, device->handle); 169 usb_log_ info("I/O regs at 0x%X (size %zu), IRQ %d.\n",169 usb_log_debug("I/O regs at 0x%X (size %zu), IRQ %d.\n", 170 170 io_reg_base, io_reg_size, irq); 171 171 … … 175 175 176 176 bool interrupts = false; 177 #ifdef CONFIG_USBHC_NO_INTERRUPTS 178 usb_log_warning("Interrupts disabled in OS config, " \ 179 "falling back to polling.\n"); 180 #else 177 181 ret = pci_enable_interrupts(device); 178 182 if (ret != EOK) { 179 usb_log_warning( 180 "Failed(%d) to enable interrupts, fall back to polling.\n", 181 ret); 183 usb_log_warning("Failed to enable interrupts: %s.\n", 184 str_error(ret)); 185 usb_log_info("HW interrupts not available, " \ 186 "falling back to polling.\n"); 182 187 } else { 183 188 usb_log_debug("Hw interrupts enabled.\n"); 184 189 interrupts = true; 185 190 } 191 #endif 186 192 187 193 instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc"); … … 190 196 "Failed(%d) to create HC function.\n", ret); 191 197 192 ret = uhci_hc_init(&instance->hc, instance->hc_fun,198 ret = hc_init(&instance->hc, instance->hc_fun, 193 199 (void*)io_reg_base, io_reg_size, interrupts); 194 200 CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret); 195 instance->hc_fun->ops = & uhci_hc_ops;201 instance->hc_fun->ops = &hc_ops; 196 202 instance->hc_fun->driver_data = &instance->hc; 197 203 ret = ddf_fun_bind(instance->hc_fun); … … 208 214 if (instance->rh_fun) \ 209 215 ddf_fun_destroy(instance->rh_fun); \ 210 uhci_hc_fini(&instance->hc); \216 hc_fini(&instance->hc); \ 211 217 return ret; \ 212 218 } … … 223 229 "Failed(%d) to create root hub function.\n", ret); 224 230 225 ret = uhci_rh_init(&instance->rh, instance->rh_fun,231 ret = rh_init(&instance->rh, instance->rh_fun, 226 232 (uintptr_t)instance->hc.registers + 0x10, 4); 227 233 CHECK_RET_FINI_RETURN(ret, 228 234 "Failed(%d) to setup UHCI root hub.\n", ret); 229 235 230 instance->rh_fun->ops = & uhci_rh_ops;236 instance->rh_fun->ops = &rh_ops; 231 237 instance->rh_fun->driver_data = &instance->rh; 232 238 ret = ddf_fun_bind(instance->rh_fun); -
uspace/drv/uhci-hcd/uhci.h
rd8421c4 rf97717d9 38 38 #include <ddf/driver.h> 39 39 40 #include " uhci_hc.h"41 #include " uhci_rh.h"40 #include "hc.h" 41 #include "root_hub.h" 42 42 43 43 typedef struct uhci { … … 45 45 ddf_fun_t *rh_fun; 46 46 47 uhci_hc_t hc;48 uhci_rh_t rh;47 hc_t hc; 48 rh_t rh; 49 49 } uhci_t; 50 50 -
uspace/drv/uhci-hcd/utils/malloc32.h
rd8421c4 rf97717d9 50 50 static inline uintptr_t addr_to_phys(void *addr) 51 51 { 52 if (addr == NULL) 53 return 0; 54 52 55 uintptr_t result; 53 56 int ret = as_get_physical_mapping(addr, &result); -
uspace/drv/uhci-rhd/main.c
rd8421c4 rf97717d9 36 36 #include <device/hw_res.h> 37 37 #include <errno.h> 38 #include <str_error.h> 38 39 #include <usb_iface.h> 39 40 #include <usb/ddfiface.h> … … 86 87 int ret = hc_get_my_registers(device, &io_regs, &io_size); 87 88 if (ret != EOK) { 88 usb_log_error("Failed (%d) to get registers from parent hc.",89 ret);90 } 91 usb_log_ info("I/O regs at %#X (size %zu).\n", io_regs, io_size);89 usb_log_error("Failed to get registers from parent HC: %s.\n", 90 str_error(ret)); 91 } 92 usb_log_debug("I/O regs at %#X (size %zu).\n", io_regs, io_size); 92 93 93 94 uhci_root_hub_t *rh = malloc(sizeof(uhci_root_hub_t)); … … 99 100 ret = uhci_root_hub_init(rh, (void*)io_regs, io_size, device); 100 101 if (ret != EOK) { 101 usb_log_error("Failed(%d) to initialize driver instance.\n", ret); 102 usb_log_error("Failed to initialize driver instance: %s.\n", 103 str_error(ret)); 102 104 free(rh); 103 105 return ret; … … 105 107 106 108 device->driver_data = rh; 107 usb_log_info(" Sucessfully initialized driver instance for device:%d.\n",108 device-> handle);109 usb_log_info("Controlling root hub `%s' (%llu).\n", 110 device->name, device->handle); 109 111 return EOK; 110 112 } … … 129 131 int main(int argc, char *argv[]) 130 132 { 131 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME); 133 printf(NAME ": HelenOS UHCI root hub driver.\n"); 134 135 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 136 132 137 return ddf_driver_main(&uhci_rh_driver); 133 138 } -
uspace/drv/uhci-rhd/port.c
rd8421c4 rf97717d9 256 256 assert(usb_hc_connection_is_opened(&port->hc_connection)); 257 257 258 usb_log_ info("%s: Detected new device.\n", port->id_string);258 usb_log_debug("%s: Detected new device.\n", port->id_string); 259 259 260 260 usb_address_t dev_addr; … … 270 270 } 271 271 272 usb_log_info(" %s: New device has address %d (handle %zu).\n",273 port-> id_string, dev_addr, port->attached_device);272 usb_log_info("New device at port %u, address %d (handle %llu).\n", 273 port->number, dev_addr, port->attached_device); 274 274 275 275 return EOK; … … 315 315 uhci_port_write_status(port, port_status); 316 316 317 usb_log_ info("%s: %sabled port.\n",317 usb_log_debug("%s: %sabled port.\n", 318 318 port->id_string, enabled ? "En" : "Dis"); 319 319 return EOK; -
uspace/drv/usbflbk/main.c
rd8421c4 rf97717d9 86 86 int main(int argc, char *argv[]) 87 87 { 88 usb_log_enable(USB_LOG_LEVEL_DE BUG, NAME);88 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 89 89 90 90 return usb_driver_main(&usbfallback_driver); -
uspace/drv/usbhub/main.c
rd8421c4 rf97717d9 76 76 printf(NAME ": HelenOS USB hub driver.\n"); 77 77 78 usb_log_enable(USB_LOG_LEVEL_DE BUG, NAME);78 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 79 79 80 80 return usb_driver_main(&usb_hub_driver); -
uspace/drv/usbhub/usbhub.c
rd8421c4 rf97717d9 132 132 return opResult; 133 133 } 134 usb_log_ info("setting port count to %d\n",descriptor->ports_count);134 usb_log_debug("setting port count to %d\n",descriptor->ports_count); 135 135 hub_info->port_count = descriptor->ports_count; 136 136 hub_info->attached_devs = (usb_hc_attached_device_t*) … … 159 159 usb_standard_device_descriptor_t *std_descriptor 160 160 = &hub_info->usb_device->descriptors.device; 161 usb_log_ info("hub has %d configurations\n",161 usb_log_debug("hub has %d configurations\n", 162 162 std_descriptor->configuration_count); 163 163 if(std_descriptor->configuration_count<1){ … … 288 288 //if this hub already uses default address, it cannot request it once more 289 289 if(hub->is_default_address_used) return; 290 usb_log_ info("some connection changed\n");290 usb_log_debug("some connection changed\n"); 291 291 assert(hub->control_pipe->hc_phone); 292 292 int opResult = usb_hub_clear_port_feature(hub->control_pipe, … … 331 331 332 332 int opResult; 333 usb_log_ info("finalizing add device\n");333 usb_log_debug("finalizing add device\n"); 334 334 opResult = usb_hub_clear_port_feature(hub->control_pipe, 335 335 port, USB_HUB_FEATURE_C_PORT_RESET); … … 363 363 return; 364 364 } 365 usb_log_ info("setting new address %d\n",new_device_address);365 usb_log_debug("setting new address %d\n",new_device_address); 366 366 //opResult = usb_drv_req_set_address(hc, USB_ADDRESS_DEFAULT, 367 367 // new_device_address); … … 403 403 return; 404 404 } 405 usb_log_info("new device address %d, handle %zu\n", 405 usb_log_info("Detected new device on `%s' (port %d), " \ 406 "address %d (handle %llu).\n", 407 hub->usb_device->ddf_dev->name, (int) port, 406 408 new_device_address, child_handle); 407 408 409 } 409 410 … … 502 503 if (usb_port_connect_change(&status)) { 503 504 if (usb_port_dev_connected(&status)) { 504 usb_log_ info("some connection changed\n");505 usb_log_debug("some connection changed\n"); 505 506 usb_hub_init_add_device(hub, port, usb_port_speed(&status)); 506 507 } else { … … 514 515 usb_hub_over_current(hub,port); 515 516 }else{ 516 usb_log_ info("over current condition was auto-resolved on port %d\n",517 usb_log_debug("over current condition was auto-resolved on port %d\n", 517 518 port); 518 519 } … … 520 521 //port reset 521 522 if (usb_port_reset_completed(&status)) { 522 usb_log_ info("port reset complete\n");523 usb_log_debug("port reset complete\n"); 523 524 if (usb_port_enabled(&status)) { 524 525 usb_hub_finalize_add_device(hub, port, usb_port_speed(&status)); -
uspace/drv/usbkbd/Makefile
rd8421c4 rf97717d9 30 30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBUSB_PREFIX)/libusb.a 31 31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBUSB_PREFIX)/include -I. 32 BINARY = usb hid32 BINARY = usbkbd 33 33 34 34 STOLEN_LAYOUT_SOURCES = \ … … 40 40 main.c \ 41 41 conv.c \ 42 hidreq.c \43 42 kbddev.c \ 44 43 kbdrepeat.c \ 45 hiddev.c \46 44 $(STOLEN_LAYOUT_SOURCES) 47 45 -
uspace/drv/usbkbd/conv.h
rd8421c4 rf97717d9 34 34 */ 35 35 36 #ifndef USB HID_CONV_H_37 #define USB HID_CONV_H_36 #ifndef USB_KBD_CONV_H_ 37 #define USB_KBD_CONV_H_ 38 38 39 39 unsigned int usbhid_parse_scancode(int scancode); 40 40 41 #endif /* USB HID_CONV_H_ */41 #endif /* USB_KBD_CONV_H_ */ 42 42 43 43 /** -
uspace/drv/usbkbd/kbddev.c
rd8421c4 rf97717d9 46 46 47 47 #include <usb/usb.h> 48 #include <usb/dp.h> 49 #include <usb/request.h> 48 50 #include <usb/classes/hid.h> 49 51 #include <usb/pipes.h> … … 52 54 #include <usb/classes/classes.h> 53 55 #include <usb/classes/hidut.h> 56 #include <usb/classes/hidreq.h> 57 #include <usb/classes/hidreport.h> 58 59 #include <usb/devdrv.h> 54 60 55 61 #include "kbddev.h" 56 #include "hiddev.h" 57 #include "hidreq.h" 62 58 63 #include "layout.h" 59 64 #include "conv.h" … … 85 90 static const unsigned int DEFAULT_REPEAT_DELAY = 50 * 1000; 86 91 92 /*----------------------------------------------------------------------------*/ 93 87 94 /** Keyboard polling endpoint description for boot protocol class. */ 88 static usb_endpoint_description_t poll_endpoint_description = {95 static usb_endpoint_description_t boot_poll_endpoint_description = { 89 96 .transfer_type = USB_TRANSFER_INTERRUPT, 90 97 .direction = USB_DIRECTION_IN, … … 95 102 }; 96 103 97 typedef enum usbhid_kbd_flags { 98 USBHID_KBD_STATUS_UNINITIALIZED = 0, 99 USBHID_KBD_STATUS_INITIALIZED = 1, 100 USBHID_KBD_STATUS_TO_DESTROY = -1 101 } usbhid_kbd_flags; 104 /* Array of endpoints expected on the device, NULL terminated. */ 105 usb_endpoint_description_t 106 *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1] = { 107 &boot_poll_endpoint_description, 108 NULL 109 }; 110 111 /*----------------------------------------------------------------------------*/ 112 113 enum { 114 BOOT_REPORT_DESCRIPTOR_SIZE = 63 115 }; 116 117 static const uint8_t BOOT_REPORT_DESCRIPTOR[BOOT_REPORT_DESCRIPTOR_SIZE] = { 118 0x05, 0x01, // Usage Page (Generic Desktop), 119 0x09, 0x06, // Usage (Keyboard), 120 0xA1, 0x01, // Collection (Application), 121 0x75, 0x01, // Report Size (1), 122 0x95, 0x08, // Report Count (8), 123 0x05, 0x07, // Usage Page (Key Codes); 124 0x19, 0xE0, // Usage Minimum (224), 125 0x29, 0xE7, // Usage Maximum (231), 126 0x15, 0x00, // Logical Minimum (0), 127 0x25, 0x01, // Logical Maximum (1), 128 0x81, 0x02, // Input (Data, Variable, Absolute), ; Modifier byte 129 0x95, 0x01, // Report Count (1), 130 0x75, 0x08, // Report Size (8), 131 0x81, 0x01, // Input (Constant), ; Reserved byte 132 0x95, 0x05, // Report Count (5), 133 0x75, 0x01, // Report Size (1), 134 0x05, 0x08, // Usage Page (Page# for LEDs), 135 0x19, 0x01, // Usage Minimum (1), 136 0x29, 0x05, // Usage Maxmimum (5), 137 0x91, 0x02, // Output (Data, Variable, Absolute), ; LED report 138 0x95, 0x01, // Report Count (1), 139 0x75, 0x03, // Report Size (3), 140 0x91, 0x01, // Output (Constant), ; LED report padding 141 0x95, 0x06, // Report Count (6), 142 0x75, 0x08, // Report Size (8), 143 0x15, 0x00, // Logical Minimum (0), 144 0x25, 0xff, // Logical Maximum (255), 145 0x05, 0x07, // Usage Page (Key Codes), 146 0x19, 0x00, // Usage Minimum (0), 147 0x29, 0xff, // Usage Maximum (255), 148 0x81, 0x00, // Input (Data, Array), ; Key arrays (6 bytes) 149 0xC0 // End Collection 150 151 }; 152 153 /*----------------------------------------------------------------------------*/ 154 155 typedef enum usb_kbd_flags { 156 USB_KBD_STATUS_UNINITIALIZED = 0, 157 USB_KBD_STATUS_INITIALIZED = 1, 158 USB_KBD_STATUS_TO_DESTROY = -1 159 } usb_kbd_flags; 102 160 103 161 /*----------------------------------------------------------------------------*/ … … 132 190 133 191 typedef enum usbhid_lock_code { 134 USB HID_LOCK_NUM = 0x53,135 USB HID_LOCK_CAPS = 0x39,136 USB HID_LOCK_SCROLL = 0x47,137 USB HID_LOCK_COUNT = 3192 USB_KBD_LOCK_NUM = 0x53, 193 USB_KBD_LOCK_CAPS = 0x39, 194 USB_KBD_LOCK_SCROLL = 0x47, 195 USB_KBD_LOCK_COUNT = 3 138 196 } usbhid_lock_code; 139 197 140 static const usbhid_lock_code usbhid_lock_codes[USB HID_LOCK_COUNT] = {141 USB HID_LOCK_NUM,142 USB HID_LOCK_CAPS,143 USB HID_LOCK_SCROLL198 static const usbhid_lock_code usbhid_lock_codes[USB_KBD_LOCK_COUNT] = { 199 USB_KBD_LOCK_NUM, 200 USB_KBD_LOCK_CAPS, 201 USB_KBD_LOCK_SCROLL 144 202 }; 145 203 … … 149 207 150 208 static void default_connection_handler(ddf_fun_t *, ipc_callid_t, ipc_call_t *); 151 staticddf_dev_ops_t keyboard_ops = {209 ddf_dev_ops_t keyboard_ops = { 152 210 .default_handler = default_connection_handler 153 211 }; … … 169 227 sysarg_t method = IPC_GET_IMETHOD(*icall); 170 228 171 usb hid_kbd_t *kbd_dev = (usbhid_kbd_t *)fun->driver_data;229 usb_kbd_t *kbd_dev = (usb_kbd_t *)fun->driver_data; 172 230 assert(kbd_dev != NULL); 173 231 … … 203 261 * @param kbd_dev Keyboard device structure. 204 262 */ 205 static void usb hid_kbd_set_led(usbhid_kbd_t *kbd_dev)263 static void usb_kbd_set_led(usb_kbd_t *kbd_dev) 206 264 { 207 265 uint8_t buffer[BOOTP_BUFFER_OUT_SIZE]; … … 237 295 usb_debug_str_buffer(buffer, BOOTP_BUFFER_OUT_SIZE, 0)); 238 296 239 assert(kbd_dev->hid_dev != NULL); 240 assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED); 241 usbhid_req_set_report(kbd_dev->hid_dev, USB_HID_REPORT_TYPE_OUTPUT, 297 assert(kbd_dev->usb_dev != NULL); 298 299 usbhid_req_set_report(&kbd_dev->usb_dev->ctrl_pipe, 300 kbd_dev->usb_dev->interface_no, USB_HID_REPORT_TYPE_OUTPUT, 242 301 buffer, BOOTP_BUFFER_OUT_SIZE); 243 302 } … … 260 319 * @param key Key code of the key according to HID Usage Tables. 261 320 */ 262 void usb hid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key)321 void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key) 263 322 { 264 323 console_event_t ev; … … 310 369 /* Update keyboard lock indicator lights. */ 311 370 if (kbd_dev->lock_keys != locks_old) { 312 usb hid_kbd_set_led(kbd_dev);371 usb_kbd_set_led(kbd_dev); 313 372 } 314 373 } else { … … 358 417 359 418 /*----------------------------------------------------------------------------*/ 360 /** 361 * Checks if modifiers were pressed or released and generates key events. 362 * 363 * @param kbd_dev Keyboard device structure. 364 * @param modifiers Bitmap of modifiers. 365 * 366 * @sa usbhid_kbd_push_ev() 367 */ 368 //static void usbhid_kbd_check_modifier_changes(usbhid_kbd_t *kbd_dev, 369 // const uint8_t *key_codes, size_t count) 370 //{ 371 // /* 372 // * TODO: why the USB keyboard has NUM_, SCROLL_ and CAPS_LOCK 373 // * both as modifiers and as keyUSB_HID_LOCK_COUNTs with their own scancodes??? 374 // * 375 // * modifiers should be sent as normal keys to usbhid_parse_scancode()!! 376 // * so maybe it would be better if I received it from report parser in 377 // * that way 378 // */ 379 380 // int i; 381 // for (i = 0; i < count; ++i) { 382 // if ((modifiers & usb_hid_modifiers_consts[i]) && 383 // !(kbd_dev->modifiers & usb_hid_modifiers_consts[i])) { 384 // // modifier pressed 385 // if (usbhid_modifiers_keycodes[i] != 0) { 386 // usbhid_kbd_push_ev(kbd_dev, KEY_PRESS, 387 // usbhid_modifiers_keycodes[i]); 388 // } 389 // } else if (!(modifiers & usb_hid_modifiers_consts[i]) && 390 // (kbd_dev->modifiers & usb_hid_modifiers_consts[i])) { 391 // // modifier released 392 // if (usbhid_modifiers_keycodes[i] != 0) { 393 // usbhid_kbd_push_ev(kbd_dev, KEY_RELEASE, 394 // usbhid_modifiers_keycodes[i]); 395 // } 396 // } // no change 397 // } 398 399 // kbd_dev->modifiers = modifiers; 400 //} 401 402 /*----------------------------------------------------------------------------*/ 403 404 static inline int usbhid_kbd_is_lock(unsigned int key_code) 419 420 static inline int usb_kbd_is_lock(unsigned int key_code) 405 421 { 406 422 return (key_code == KC_NUM_LOCK … … 414 430 * 415 431 * An event is created only when key is pressed or released. Besides handling 416 * the events (usb hid_kbd_push_ev()), the auto-repeat fibril is notified about417 * key presses and releases (see usb hid_kbd_repeat_start() and418 * usb hid_kbd_repeat_stop()).432 * the events (usb_kbd_push_ev()), the auto-repeat fibril is notified about 433 * key presses and releases (see usb_kbd_repeat_start() and 434 * usb_kbd_repeat_stop()). 419 435 * 420 436 * @param kbd_dev Keyboard device structure. … … 423 439 * @param count Number of key codes in report (size of the report). 424 440 * 425 * @sa usb hid_kbd_push_ev(), usbhid_kbd_repeat_start(), usbhid_kbd_repeat_stop()426 */ 427 static void usb hid_kbd_check_key_changes(usbhid_kbd_t *kbd_dev,441 * @sa usb_kbd_push_ev(), usb_kbd_repeat_start(), usb_kbd_repeat_stop() 442 */ 443 static void usb_kbd_check_key_changes(usb_kbd_t *kbd_dev, 428 444 const uint8_t *key_codes, size_t count) 429 445 { … … 434 450 * First of all, check if the kbd have reported phantom state. 435 451 * 436 * TODO:this must be changed as we don't know which keys are modifiers452 * this must be changed as we don't know which keys are modifiers 437 453 * and which are regular keys. 438 454 */ … … 466 482 // not found, i.e. the key was released 467 483 key = usbhid_parse_scancode(kbd_dev->keys[j]); 468 if (!usb hid_kbd_is_lock(key)) {469 usb hid_kbd_repeat_stop(kbd_dev, key);484 if (!usb_kbd_is_lock(key)) { 485 usb_kbd_repeat_stop(kbd_dev, key); 470 486 } 471 usb hid_kbd_push_ev(kbd_dev, KEY_RELEASE, key);487 usb_kbd_push_ev(kbd_dev, KEY_RELEASE, key); 472 488 usb_log_debug2("Key released: %d\n", key); 473 489 } else { … … 491 507 usb_log_debug2("Key pressed: %d (keycode: %d)\n", key, 492 508 key_codes[i]); 493 usb hid_kbd_push_ev(kbd_dev, KEY_PRESS, key);494 if (!usb hid_kbd_is_lock(key)) {495 usb hid_kbd_repeat_start(kbd_dev, key);509 usb_kbd_push_ev(kbd_dev, KEY_PRESS, key); 510 if (!usb_kbd_is_lock(key)) { 511 usb_kbd_repeat_start(kbd_dev, key); 496 512 } 497 513 } else { … … 523 539 * structure representing the keyboard. 524 540 * 525 * @sa usb hid_kbd_check_key_changes(), usbhid_kbd_check_modifier_changes()526 */ 527 static void usb hid_kbd_process_keycodes(const uint8_t *key_codes, size_t count,541 * @sa usb_kbd_check_key_changes(), usb_kbd_check_modifier_changes() 542 */ 543 static void usb_kbd_process_keycodes(const uint8_t *key_codes, size_t count, 528 544 uint8_t modifiers, void *arg) 529 545 { … … 534 550 } 535 551 536 usb hid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg;552 usb_kbd_t *kbd_dev = (usb_kbd_t *)arg; 537 553 assert(kbd_dev != NULL); 538 554 … … 546 562 } 547 563 548 ///usb hid_kbd_check_modifier_changes(kbd_dev, key_codes, count);549 usb hid_kbd_check_key_changes(kbd_dev, key_codes, count);564 ///usb_kbd_check_modifier_changes(kbd_dev, key_codes, count); 565 usb_kbd_check_key_changes(kbd_dev, key_codes, count); 550 566 } 551 567 … … 558 574 * This function uses the HID report parser to translate the data received from 559 575 * the device into generic USB HID key codes and into generic modifiers bitmap. 560 * The parser then calls the given callback (usb hid_kbd_process_keycodes()).576 * The parser then calls the given callback (usb_kbd_process_keycodes()). 561 577 * 562 578 * @note Currently, only the boot protocol is supported. … … 566 582 * @param actual_size Size of the data from keyboard (report size) in bytes. 567 583 * 568 * @sa usbhid_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(). 569 */ 570 static void usbhid_kbd_process_data(usbhid_kbd_t *kbd_dev, 584 * @sa usb_kbd_process_keycodes(), usb_hid_boot_keyboard_input_report(), 585 * usb_hid_parse_report(). 586 */ 587 static void usb_kbd_process_data(usb_kbd_t *kbd_dev, 571 588 uint8_t *buffer, size_t actual_size) 572 589 { 573 assert(kbd_dev->initialized == USB HID_KBD_STATUS_INITIALIZED);574 assert(kbd_dev-> hid_dev->parser != NULL);590 assert(kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); 591 assert(kbd_dev->parser != NULL); 575 592 576 593 usb_hid_report_in_callbacks_t *callbacks = … … 578 595 sizeof(usb_hid_report_in_callbacks_t)); 579 596 580 callbacks->keyboard = usb hid_kbd_process_keycodes;597 callbacks->keyboard = usb_kbd_process_keycodes; 581 598 582 599 usb_log_debug("Calling usb_hid_parse_report() with " … … 585 602 // int rc = usb_hid_boot_keyboard_input_report(buffer, actual_size, 586 603 // callbacks, kbd_dev); 587 int rc = usb_hid_parse_report(kbd_dev->hid_dev->parser, buffer, 588 actual_size, callbacks, kbd_dev); 604 usb_hid_report_path_t *path = usb_hid_report_path(); 605 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 606 607 int rc = usb_hid_parse_report(kbd_dev->parser, buffer, 608 actual_size, path, USB_HID_PATH_COMPARE_STRICT, callbacks, kbd_dev); 609 610 usb_hid_report_path_free (path); 589 611 590 612 if (rc != EOK) { … … 597 619 /* HID/KBD structure manipulation */ 598 620 /*----------------------------------------------------------------------------*/ 621 622 static void usb_kbd_mark_unusable(usb_kbd_t *kbd_dev) 623 { 624 kbd_dev->initialized = USB_KBD_STATUS_TO_DESTROY; 625 } 626 627 628 /*----------------------------------------------------------------------------*/ 629 /* API functions */ 630 /*----------------------------------------------------------------------------*/ 599 631 /** 600 632 * Creates a new USB/HID keyboard structure. 601 633 * 602 634 * The structure returned by this function is not initialized. Use 603 * usb hid_kbd_init() to initialize it prior to polling.635 * usb_kbd_init() to initialize it prior to polling. 604 636 * 605 637 * @return New uninitialized structure for representing a USB/HID keyboard or 606 638 * NULL if not successful (memory error). 607 639 */ 608 static usbhid_kbd_t *usbhid_kbd_new(void)609 { 610 usb hid_kbd_t *kbd_dev =611 (usb hid_kbd_t *)malloc(sizeof(usbhid_kbd_t));640 usb_kbd_t *usb_kbd_new(void) 641 { 642 usb_kbd_t *kbd_dev = 643 (usb_kbd_t *)malloc(sizeof(usb_kbd_t)); 612 644 613 645 if (kbd_dev == NULL) { … … 616 648 } 617 649 618 memset(kbd_dev, 0, sizeof(usbhid_kbd_t)); 619 620 kbd_dev->hid_dev = usbhid_dev_new(); 621 if (kbd_dev->hid_dev == NULL) { 622 usb_log_fatal("Could not create HID device structure.\n"); 650 memset(kbd_dev, 0, sizeof(usb_kbd_t)); 651 652 kbd_dev->parser = (usb_hid_report_parser_t *)(malloc(sizeof( 653 usb_hid_report_parser_t))); 654 if (kbd_dev->parser == NULL) { 655 usb_log_fatal("No memory!\n"); 656 free(kbd_dev); 623 657 return NULL; 624 658 } 625 659 626 660 kbd_dev->console_phone = -1; 627 kbd_dev->initialized = USB HID_KBD_STATUS_UNINITIALIZED;661 kbd_dev->initialized = USB_KBD_STATUS_UNINITIALIZED; 628 662 629 663 return kbd_dev; 630 }631 632 /*----------------------------------------------------------------------------*/633 634 static void usbhid_kbd_mark_unusable(usbhid_kbd_t *kbd_dev)635 {636 kbd_dev->initialized = USBHID_KBD_STATUS_TO_DESTROY;637 664 } 638 665 … … 658 685 * @return Other value inherited from function usbhid_dev_init(). 659 686 */ 660 static int usbhid_kbd_init(usbhid_kbd_t *kbd_dev, ddf_dev_t *dev)687 int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev) 661 688 { 662 689 int rc; 663 690 664 usb_log_ info("Initializing HID/KBD structure...\n");691 usb_log_debug("Initializing HID/KBD structure...\n"); 665 692 666 693 if (kbd_dev == NULL) { … … 671 698 672 699 if (dev == NULL) { 673 usb_log_error("Failed to init keyboard structure: no device"700 usb_log_error("Failed to init keyboard structure: no USB device" 674 701 " given.\n"); 675 702 return EINVAL; 676 703 } 677 704 678 if (kbd_dev->initialized == USB HID_KBD_STATUS_INITIALIZED) {705 if (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED) { 679 706 usb_log_warning("Keyboard structure already initialized.\n"); 680 707 return EINVAL; 681 708 } 682 709 683 rc = usbhid_dev_init(kbd_dev->hid_dev, dev, &poll_endpoint_description); 684 710 /* TODO: does not work! */ 711 if (!dev->pipes[USB_KBD_POLL_EP_NO].present) { 712 usb_log_warning("Required endpoint not found - probably not " 713 "a supported device.\n"); 714 return ENOTSUP; 715 } 716 717 /* The USB device should already be initialized, save it in structure */ 718 kbd_dev->usb_dev = dev; 719 720 /* Initialize the report parser. */ 721 rc = usb_hid_parser_init(kbd_dev->parser); 685 722 if (rc != EOK) { 686 usb_log_error("Failed to initialize HID device structure: %s\n", 687 str_error(rc)); 723 usb_log_error("Failed to initialize report parser.\n"); 688 724 return rc; 689 725 } 690 726 691 assert(kbd_dev->hid_dev->initialized == USBHID_KBD_STATUS_INITIALIZED); 692 693 // save the size of the report (boot protocol report by default) 694 // kbd_dev->key_count = BOOTP_REPORT_SIZE; 695 696 usb_hid_report_path_t path; 697 path.usage_page = USB_HIDUT_PAGE_KEYBOARD; 727 /* Get the report descriptor and parse it. */ 728 rc = usb_hid_process_report_descriptor(kbd_dev->usb_dev, 729 kbd_dev->parser); 730 if (rc != EOK) { 731 usb_log_warning("Could not process report descriptor, " 732 "falling back to boot protocol.\n"); 733 rc = usb_hid_parse_report_descriptor(kbd_dev->parser, 734 BOOT_REPORT_DESCRIPTOR, BOOT_REPORT_DESCRIPTOR_SIZE); 735 if (rc != EOK) { 736 usb_log_error("Failed to parse boot report descriptor:" 737 " %s.\n", str_error(rc)); 738 return rc; 739 } 740 741 rc = usbhid_req_set_protocol(&kbd_dev->usb_dev->ctrl_pipe, 742 kbd_dev->usb_dev->interface_no, USB_HID_PROTOCOL_BOOT); 743 744 if (rc != EOK) { 745 usb_log_warning("Failed to set boot protocol to the " 746 "device: %s\n", str_error(rc)); 747 return rc; 748 } 749 } 750 751 /* 752 * TODO: make more general 753 */ 754 usb_hid_report_path_t *path = usb_hid_report_path(); 755 usb_hid_report_path_append_item(path, USB_HIDUT_PAGE_KEYBOARD, 0); 698 756 kbd_dev->key_count = usb_hid_report_input_length( 699 kbd_dev->hid_dev->parser, &path); 757 kbd_dev->parser, path, USB_HID_PATH_COMPARE_STRICT); 758 usb_hid_report_path_free (path); 700 759 701 760 usb_log_debug("Size of the input report: %zu\n", kbd_dev->key_count); … … 729 788 730 789 /* 731 * Set boot protocol.732 790 * Set LEDs according to initial setup. 733 791 * Set Idle rate 734 792 */ 735 assert(kbd_dev->hid_dev != NULL); 736 assert(kbd_dev->hid_dev->initialized); 737 //usbhid_req_set_protocol(kbd_dev->hid_dev, USB_HID_PROTOCOL_BOOT); 738 739 usbhid_kbd_set_led(kbd_dev); 740 741 usbhid_req_set_idle(kbd_dev->hid_dev, IDLE_RATE); 742 743 kbd_dev->initialized = USBHID_KBD_STATUS_INITIALIZED; 744 usb_log_info("HID/KBD device structure initialized.\n"); 793 usb_kbd_set_led(kbd_dev); 794 795 usbhid_req_set_idle(&kbd_dev->usb_dev->ctrl_pipe, 796 kbd_dev->usb_dev->interface_no, IDLE_RATE); 797 798 kbd_dev->initialized = USB_KBD_STATUS_INITIALIZED; 799 usb_log_debug("HID/KBD device structure initialized.\n"); 745 800 746 801 return EOK; … … 748 803 749 804 /*----------------------------------------------------------------------------*/ 750 /* HID/KBD polling */ 751 /*----------------------------------------------------------------------------*/ 752 /** 753 * Main keyboard polling function. 754 * 755 * This function uses the Interrupt In pipe of the keyboard to poll for events. 756 * The keyboard is initialized in a way that it reports only when a key is 757 * pressed or released, so there is no actual need for any sleeping between 758 * polls (see usbhid_kbd_try_add_device() or usbhid_kbd_init()). 759 * 760 * @param kbd_dev Initialized keyboard structure representing the device to 761 * poll. 762 * 763 * @sa usbhid_kbd_process_data() 764 */ 765 static void usbhid_kbd_poll(usbhid_kbd_t *kbd_dev) 766 { 767 int rc, sess_rc; 768 uint8_t buffer[BOOTP_BUFFER_SIZE]; 769 size_t actual_size; 770 771 usb_log_info("Polling keyboard...\n"); 772 773 if (!kbd_dev->initialized) { 774 usb_log_error("HID/KBD device not initialized!\n"); 775 return; 776 } 777 778 assert(kbd_dev->hid_dev != NULL); 779 assert(kbd_dev->hid_dev->initialized); 780 781 while (true) { 782 sess_rc = usb_pipe_start_session( 783 &kbd_dev->hid_dev->poll_pipe); 784 if (sess_rc != EOK) { 785 usb_log_warning("Failed to start a session: %s.\n", 786 str_error(sess_rc)); 787 break; 788 } 789 790 rc = usb_pipe_read(&kbd_dev->hid_dev->poll_pipe, 791 buffer, BOOTP_BUFFER_SIZE, &actual_size); 792 793 sess_rc = usb_pipe_end_session( 794 &kbd_dev->hid_dev->poll_pipe); 795 796 if (rc != EOK) { 797 usb_log_warning("Error polling the keyboard: %s.\n", 798 str_error(rc)); 799 break; 800 } 801 802 if (sess_rc != EOK) { 803 usb_log_warning("Error closing session: %s.\n", 804 str_error(sess_rc)); 805 break; 806 } 807 808 /* 809 * If the keyboard answered with NAK, it returned no data. 810 * This implies that no change happened since last query. 811 */ 812 if (actual_size == 0) { 813 usb_log_debug("Keyboard returned NAK\n"); 814 continue; 815 } 816 817 /* 818 * TODO: Process pressed keys. 819 */ 820 usb_log_debug("Calling usbhid_kbd_process_data()\n"); 821 usbhid_kbd_process_data(kbd_dev, buffer, actual_size); 822 823 // disabled for now, no reason to sleep 824 //async_usleep(kbd_dev->hid_dev->poll_interval); 825 } 826 } 827 828 /*----------------------------------------------------------------------------*/ 829 /** 830 * Function executed by the main driver fibril. 831 * 832 * Just starts polling the keyboard for events. 833 * 834 * @param arg Initialized keyboard device structure (of type usbhid_kbd_t) 835 * representing the device. 836 * 837 * @retval EOK if the fibril finished polling the device. 838 * @retval EINVAL if no device was given in the argument. 839 * 840 * @sa usbhid_kbd_poll() 841 * 842 * @todo Change return value - only case when the fibril finishes is in case 843 * of some error, so the error should probably be propagated from function 844 * usbhid_kbd_poll() to here and up. 845 */ 846 static int usbhid_kbd_fibril(void *arg) 847 { 848 if (arg == NULL) { 849 usb_log_error("No device!\n"); 850 return EINVAL; 851 } 852 853 usbhid_kbd_t *kbd_dev = (usbhid_kbd_t *)arg; 854 855 usbhid_kbd_poll(kbd_dev); 856 857 // as there is another fibril using this device, so we must leave the 858 // structure to it, but mark it for destroying. 859 usbhid_kbd_mark_unusable(kbd_dev); 860 // at the end, properly destroy the KBD structure 861 // usbhid_kbd_free(&kbd_dev); 862 // assert(kbd_dev == NULL); 863 864 return EOK; 865 } 866 867 /*----------------------------------------------------------------------------*/ 868 /* API functions */ 869 /*----------------------------------------------------------------------------*/ 870 /** 871 * Function for adding a new device of type USB/HID/keyboard. 872 * 873 * This functions initializes required structures from the device's descriptors 874 * and starts new fibril for polling the keyboard for events and another one for 875 * handling auto-repeat of keys. 876 * 877 * During initialization, the keyboard is switched into boot protocol, the idle 878 * rate is set to 0 (infinity), resulting in the keyboard only reporting event 879 * when a key is pressed or released. Finally, the LED lights are turned on 880 * according to the default setup of lock keys. 881 * 882 * @note By default, the keyboards is initialized with Num Lock turned on and 883 * other locks turned off. 884 * @note Currently supports only boot-protocol keyboards. 885 * 886 * @param dev Device to add. 887 * 888 * @retval EOK if successful. 889 * @retval ENOMEM if there 890 * @return Other error code inherited from one of functions usbhid_kbd_init(), 891 * ddf_fun_bind() and ddf_fun_add_to_class(). 892 * 893 * @sa usbhid_kbd_fibril(), usbhid_kbd_repeat_fibril() 894 */ 895 int usbhid_kbd_try_add_device(ddf_dev_t *dev) 896 { 897 /* 898 * Create default function. 899 */ 900 ddf_fun_t *kbd_fun = ddf_fun_create(dev, fun_exposed, "keyboard"); 901 if (kbd_fun == NULL) { 902 usb_log_error("Could not create DDF function node.\n"); 903 return ENOMEM; 904 } 905 906 /* 907 * Initialize device (get and process descriptors, get address, etc.) 908 */ 909 usb_log_info("Initializing USB/HID KBD device...\n"); 910 911 usbhid_kbd_t *kbd_dev = usbhid_kbd_new(); 912 if (kbd_dev == NULL) { 913 usb_log_error("Error while creating USB/HID KBD device " 914 "structure.\n"); 915 ddf_fun_destroy(kbd_fun); 916 return ENOMEM; // TODO: some other code?? 917 } 918 919 int rc = usbhid_kbd_init(kbd_dev, dev); 920 921 if (rc != EOK) { 922 usb_log_error("Failed to initialize USB/HID KBD device.\n"); 923 ddf_fun_destroy(kbd_fun); 924 usbhid_kbd_free(&kbd_dev); 925 return rc; 926 } 927 928 usb_log_info("USB/HID KBD device structure initialized.\n"); 929 930 /* 931 * Store the initialized keyboard device and keyboard ops 932 * to the DDF function. 933 */ 934 kbd_fun->driver_data = kbd_dev; 935 kbd_fun->ops = &keyboard_ops; 936 937 rc = ddf_fun_bind(kbd_fun); 938 if (rc != EOK) { 939 usb_log_error("Could not bind DDF function.\n"); 940 // TODO: Can / should I destroy the DDF function? 941 ddf_fun_destroy(kbd_fun); 942 usbhid_kbd_free(&kbd_dev); 943 return rc; 944 } 945 946 rc = ddf_fun_add_to_class(kbd_fun, "keyboard"); 947 if (rc != EOK) { 948 usb_log_error("Could not add DDF function to class 'keyboard'" 949 "\n"); 950 // TODO: Can / should I destroy the DDF function? 951 ddf_fun_destroy(kbd_fun); 952 usbhid_kbd_free(&kbd_dev); 953 return rc; 954 } 955 956 /* 957 * Create new fibril for handling this keyboard 958 */ 959 fid_t fid = fibril_create(usbhid_kbd_fibril, kbd_dev); 960 if (fid == 0) { 961 usb_log_error("Failed to start fibril for KBD device\n"); 962 return ENOMEM; 963 } 964 fibril_add_ready(fid); 965 966 /* 967 * Create new fibril for auto-repeat 968 */ 969 fid = fibril_create(usbhid_kbd_repeat_fibril, kbd_dev); 970 if (fid == 0) { 971 usb_log_error("Failed to start fibril for KBD auto-repeat"); 972 return ENOMEM; 973 } 974 fibril_add_ready(fid); 975 976 (void)keyboard_ops; 977 978 /* 979 * Hurrah, device is initialized. 980 */ 981 return EOK; 982 } 983 984 /*----------------------------------------------------------------------------*/ 985 986 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev) 987 { 988 return (kbd_dev->initialized == USBHID_KBD_STATUS_INITIALIZED); 805 806 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer, 807 size_t buffer_size, void *arg) 808 { 809 if (dev == NULL || buffer == NULL || arg == NULL) { 810 // do not continue polling (???) 811 return false; 812 } 813 814 usb_kbd_t *kbd_dev = (usb_kbd_t *)arg; 815 816 // TODO: add return value from this function 817 usb_kbd_process_data(kbd_dev, buffer, buffer_size); 818 819 return true; 820 } 821 822 /*----------------------------------------------------------------------------*/ 823 824 void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason, 825 void *arg) 826 { 827 if (dev == NULL || arg == NULL) { 828 return; 829 } 830 831 usb_kbd_t *kbd = (usb_kbd_t *)arg; 832 833 usb_kbd_mark_unusable(kbd); 834 } 835 836 /*----------------------------------------------------------------------------*/ 837 838 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev) 839 { 840 return (kbd_dev->initialized == USB_KBD_STATUS_INITIALIZED); 841 } 842 843 /*----------------------------------------------------------------------------*/ 844 845 int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev) 846 { 847 return (kbd_dev->initialized == USB_KBD_STATUS_TO_DESTROY); 989 848 } 990 849 … … 995 854 * @param kbd_dev Pointer to the structure to be destroyed. 996 855 */ 997 void usb hid_kbd_free(usbhid_kbd_t **kbd_dev)856 void usb_kbd_free(usb_kbd_t **kbd_dev) 998 857 { 999 858 if (kbd_dev == NULL || *kbd_dev == NULL) { … … 1004 863 async_hangup((*kbd_dev)->console_phone); 1005 864 1006 if ((*kbd_dev)->hid_dev != NULL) {1007 usbhid_dev_free(&(*kbd_dev)->hid_dev);1008 assert((*kbd_dev)->hid_dev == NULL);1009 }865 // if ((*kbd_dev)->hid_dev != NULL) { 866 // usbhid_dev_free(&(*kbd_dev)->hid_dev); 867 // assert((*kbd_dev)->hid_dev == NULL); 868 // } 1010 869 1011 870 if ((*kbd_dev)->repeat_mtx != NULL) { … … 1014 873 free((*kbd_dev)->repeat_mtx); 1015 874 } 875 876 // destroy the parser 877 if ((*kbd_dev)->parser != NULL) { 878 usb_hid_free_report_parser((*kbd_dev)->parser); 879 } 880 881 /* TODO: what about the USB device structure?? */ 1016 882 1017 883 free(*kbd_dev); -
uspace/drv/usbkbd/kbddev.h
rd8421c4 rf97717d9 34 34 */ 35 35 36 #ifndef USB HID_KBDDEV_H_37 #define USB HID_KBDDEV_H_36 #ifndef USB_KBDDEV_H_ 37 #define USB_KBDDEV_H_ 38 38 39 39 #include <stdint.h> … … 45 45 #include <ddf/driver.h> 46 46 #include <usb/pipes.h> 47 #include <usb/devdrv.h> 47 48 48 #include " hiddev.h"49 #include "kbdrepeat.h" 49 50 50 51 /*----------------------------------------------------------------------------*/ 51 /**52 * Structure for keeping information needed for auto-repeat of keys.53 */54 typedef struct {55 /** Last pressed key. */56 unsigned int key_new;57 /** Key to be repeated. */58 unsigned int key_repeated;59 /** Delay before first repeat in microseconds. */60 unsigned int delay_before;61 /** Delay between repeats in microseconds. */62 unsigned int delay_between;63 } usbhid_kbd_repeat_t;64 65 52 /** 66 53 * USB/HID keyboard device type. … … 75 62 * being device-specific. 76 63 */ 77 typedef struct { 78 /** Structure holding generic USB/HID device information. */ 79 usbhid_dev_t *hid_dev; 64 typedef struct usb_kbd_t { 65 /** Structure holding generic USB device information. */ 66 //usbhid_dev_t *hid_dev; 67 usb_device_t *usb_dev; 80 68 81 69 /** Currently pressed keys (not translated to key codes). */ … … 96 84 97 85 /** Information for auto-repeat of keys. */ 98 usb hid_kbd_repeat_t repeat;86 usb_kbd_repeat_t repeat; 99 87 100 88 /** Mutex for accessing the information about auto-repeat. */ 101 89 fibril_mutex_t *repeat_mtx; 90 91 /** Report descriptor. */ 92 uint8_t *report_desc; 93 94 /** Report descriptor size. */ 95 size_t report_desc_size; 96 97 /** HID Report parser. */ 98 usb_hid_report_parser_t *parser; 102 99 103 100 /** State of the structure (for checking before use). … … 108 105 */ 109 106 int initialized; 110 } usb hid_kbd_t;107 } usb_kbd_t; 111 108 112 109 /*----------------------------------------------------------------------------*/ 113 110 114 int usbhid_kbd_try_add_device(ddf_dev_t *dev); 111 enum { 112 USB_KBD_POLL_EP_NO = 0, 113 USB_KBD_POLL_EP_COUNT = 1 114 }; 115 115 116 int usbhid_kbd_is_usable(const usbhid_kbd_t *kbd_dev);116 usb_endpoint_description_t *usb_kbd_endpoints[USB_KBD_POLL_EP_COUNT + 1]; 117 117 118 void usbhid_kbd_free(usbhid_kbd_t **kbd_dev);118 ddf_dev_ops_t keyboard_ops; 119 119 120 void usbhid_kbd_push_ev(usbhid_kbd_t *kbd_dev, int type, unsigned int key); 120 /*----------------------------------------------------------------------------*/ 121 121 122 #endif /* USBHID_KBDDEV_H_ */ 122 usb_kbd_t *usb_kbd_new(void); 123 124 int usb_kbd_init(usb_kbd_t *kbd_dev, usb_device_t *dev); 125 126 bool usb_kbd_polling_callback(usb_device_t *dev, uint8_t *buffer, 127 size_t buffer_size, void *arg); 128 129 void usb_kbd_polling_ended_callback(usb_device_t *dev, bool reason, 130 void *arg); 131 132 int usb_kbd_is_initialized(const usb_kbd_t *kbd_dev); 133 134 int usb_kbd_is_ready_to_destroy(const usb_kbd_t *kbd_dev); 135 136 void usb_kbd_free(usb_kbd_t **kbd_dev); 137 138 void usb_kbd_push_ev(usb_kbd_t *kbd_dev, int type, unsigned int key); 139 140 #endif /* USB_KBDDEV_H_ */ 123 141 124 142 /** -
uspace/drv/usbkbd/kbdrepeat.c
rd8421c4 rf97717d9 62 62 * 63 63 * If the currently repeated key is not pressed any more ( 64 * usb hid_kbd_repeat_stop() was called), it stops repeating it and starts64 * usb_kbd_repeat_stop() was called), it stops repeating it and starts 65 65 * checking again. 66 66 * … … 70 70 * @param kbd Keyboard device structure. 71 71 */ 72 static void usb hid_kbd_repeat_loop(usbhid_kbd_t *kbd)72 static void usb_kbd_repeat_loop(usb_kbd_t *kbd) 73 73 { 74 74 unsigned int delay = 0; … … 78 78 while (true) { 79 79 // check if the kbd structure is usable 80 if (!usbhid_kbd_is_usable(kbd)) { 81 usbhid_kbd_free(&kbd); 82 assert(kbd == NULL); 80 if (!usb_kbd_is_initialized(kbd)) { 81 if (usb_kbd_is_ready_to_destroy(kbd)) { 82 usb_kbd_free(&kbd); 83 assert(kbd == NULL); 84 } 83 85 return; 84 86 } … … 90 92 usb_log_debug2("Repeating key: %u.\n", 91 93 kbd->repeat.key_repeated); 92 usb hid_kbd_push_ev(kbd, KEY_PRESS,94 usb_kbd_push_ev(kbd, KEY_PRESS, 93 95 kbd->repeat.key_repeated); 94 96 delay = kbd->repeat.delay_between; … … 125 127 * @retval EINVAL if no argument is supplied. 126 128 */ 127 int usb hid_kbd_repeat_fibril(void *arg)129 int usb_kbd_repeat_fibril(void *arg) 128 130 { 129 131 usb_log_debug("Autorepeat fibril spawned.\n"); … … 134 136 } 135 137 136 usb hid_kbd_t *kbd = (usbhid_kbd_t *)arg;138 usb_kbd_t *kbd = (usb_kbd_t *)arg; 137 139 138 usb hid_kbd_repeat_loop(kbd);140 usb_kbd_repeat_loop(kbd); 139 141 140 142 return EOK; … … 152 154 * @param key Key to start repeating. 153 155 */ 154 void usb hid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key)156 void usb_kbd_repeat_start(usb_kbd_t *kbd, unsigned int key) 155 157 { 156 158 fibril_mutex_lock(kbd->repeat_mtx); … … 170 172 * @param key Key to stop repeating. 171 173 */ 172 void usb hid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key)174 void usb_kbd_repeat_stop(usb_kbd_t *kbd, unsigned int key) 173 175 { 174 176 fibril_mutex_lock(kbd->repeat_mtx); -
uspace/drv/usbkbd/kbdrepeat.h
rd8421c4 rf97717d9 34 34 */ 35 35 36 #ifndef USB HID_KBDREPEAT_H_37 #define USB HID_KBDREPEAT_H_36 #ifndef USB_KBDREPEAT_H_ 37 #define USB_KBDREPEAT_H_ 38 38 39 #include "kbddev.h" 39 struct usb_kbd_t; 40 41 /*----------------------------------------------------------------------------*/ 42 /** 43 * Structure for keeping information needed for auto-repeat of keys. 44 */ 45 typedef struct { 46 /** Last pressed key. */ 47 unsigned int key_new; 48 /** Key to be repeated. */ 49 unsigned int key_repeated; 50 /** Delay before first repeat in microseconds. */ 51 unsigned int delay_before; 52 /** Delay between repeats in microseconds. */ 53 unsigned int delay_between; 54 } usb_kbd_repeat_t; 40 55 41 56 /*----------------------------------------------------------------------------*/ 42 57 43 int usb hid_kbd_repeat_fibril(void *arg);58 int usb_kbd_repeat_fibril(void *arg); 44 59 45 void usb hid_kbd_repeat_start(usbhid_kbd_t *kbd, unsigned int key);60 void usb_kbd_repeat_start(struct usb_kbd_t *kbd, unsigned int key); 46 61 47 void usb hid_kbd_repeat_stop(usbhid_kbd_t *kbd, unsigned int key);62 void usb_kbd_repeat_stop(struct usb_kbd_t *kbd, unsigned int key); 48 63 49 #endif /* USB HID_KBDREPEAT_H_ */64 #endif /* USB_KBDREPEAT_H_ */ 50 65 51 66 /** -
uspace/drv/usbkbd/layout.h
rd8421c4 rf97717d9 36 36 */ 37 37 38 #ifndef USB HID_LAYOUT_H_39 #define USB HID_LAYOUT_H_38 #ifndef USB_KBD_LAYOUT_H_ 39 #define USB_KBD_LAYOUT_H_ 40 40 41 41 #include <sys/types.h> -
uspace/drv/usbmid/main.c
rd8421c4 rf97717d9 106 106 printf(NAME ": USB multi interface device driver.\n"); 107 107 108 usb_log_enable(USB_LOG_LEVEL_ INFO, NAME);108 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 109 109 return ddf_driver_main(&mid_driver); 110 110 } -
uspace/drv/usbmouse/main.c
rd8421c4 rf97717d9 90 90 int main(int argc, char *argv[]) 91 91 { 92 usb_log_enable(USB_LOG_LEVEL_DE BUG, NAME);92 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 93 93 94 94 return usb_driver_main(&mouse_driver); -
uspace/drv/vhc/hcd.c
rd8421c4 rf97717d9 122 122 //sleep(5); 123 123 124 usb_log_enable(USB_LOG_LEVEL_DE BUG, NAME);124 usb_log_enable(USB_LOG_LEVEL_DEFAULT, NAME); 125 125 126 126 printf(NAME ": virtual USB host controller driver.\n"); -
uspace/lib/usb/Makefile
rd8421c4 rf97717d9 50 50 src/usb.c \ 51 51 src/usbdevice.c \ 52 src/hidreq.c \ 53 src/hidreport.c \ 52 54 src/host/device_keeper.c \ 53 55 src/host/batch.c -
uspace/lib/usb/include/usb/classes/hidparser.h
rd8421c4 rf97717d9 70 70 * Description of path of usage pages and usages in report descriptor 71 71 */ 72 #define USB_HID_PATH_COMPARE_STRICT 0 73 #define USB_HID_PATH_COMPARE_END 1 74 #define USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY 4 75 72 76 typedef struct { 73 77 int32_t usage_page; 78 int32_t usage; 79 80 link_t link; 81 } usb_hid_report_usage_path_t; 82 83 typedef struct { 84 int depth; 85 link_t link; 74 86 } usb_hid_report_path_t; 75 87 … … 79 91 typedef struct { 80 92 int32_t id; 81 int32_t usage_page;82 int32_t usage;83 93 int32_t usage_minimum; 84 94 int32_t usage_maximum; … … 107 117 uint8_t item_flags; 108 118 119 usb_hid_report_path_t *usage_path; 109 120 link_t link; 110 121 } usb_hid_report_item_t; … … 117 128 link_t feature; 118 129 } usb_hid_report_parser_t; 119 120 130 121 131 … … 194 204 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 195 205 const uint8_t *data, size_t size, 206 usb_hid_report_path_t *path, int flags, 196 207 const usb_hid_report_in_callbacks_t *callbacks, void *arg); 197 208 198 209 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 199 const usb_hid_report_path_t *path);210 usb_hid_report_path_t *path, int flags); 200 211 201 212 … … 204 215 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser); 205 216 217 /* usage path functions */ 218 usb_hid_report_path_t *usb_hid_report_path(void); 219 void usb_hid_report_path_free(usb_hid_report_path_t *path); 220 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, int32_t usage_page, int32_t usage); 221 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path); 222 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path); 223 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data); 224 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, usb_hid_report_path_t *path, int flags); 225 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path); 226 227 228 // output 229 // - funkce co vrati cesty poli v output reportu 230 // - funkce co pro danou cestu nastavi data 231 // - finalize 232 206 233 #endif 207 234 /** -
uspace/lib/usb/include/usb/classes/hidreport.h
rd8421c4 rf97717d9 1 1 /* 2 * Copyright (c) 201 0Lubos Slovak2 * Copyright (c) 2011 Lubos Slovak 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 /** @addtogroup drvusbhid29 /** @addtogroup libusb 30 30 * @{ 31 31 */ 32 32 /** @file 33 * Descriptor dumping.33 * USB HID report parser initialization from descriptors. 34 34 */ 35 35 36 #ifndef USBHID_DESCDUMP_H_37 #define USBHID_DESCDUMP_H_36 #ifndef LIBUSB_HIDREPORT_H_ 37 #define LIBUSB_HIDREPORT_H_ 38 38 39 #include <usb/de scriptor.h>40 #include <usb/classes/hid .h>39 #include <usb/devdrv.h> 40 #include <usb/classes/hidparser.h> 41 41 42 void dump_standard_configuration_descriptor( 43 int index, const usb_standard_configuration_descriptor_t *d); 42 /** 43 * Retrieves the Report descriptor from the USB device and initializes the 44 * report parser. 45 * 46 * \param dev USB device representing a HID device. 47 * \param parser HID Report parser. 48 * 49 * \retval EOK if successful. 50 * \retval EINVAL if one of the parameters is not given (is NULL). 51 * \retval ENOENT if there are some descriptors missing. 52 * \retval ENOMEM if an error with allocation occured. 53 * \retval EINVAL if the Report descriptor's size does not match the size 54 * from the interface descriptor. 55 * \return Other value inherited from function usb_pipe_start_session(), 56 * usb_pipe_end_session() or usb_request_get_descriptor(). 57 */ 58 int usb_hid_process_report_descriptor(usb_device_t *dev, 59 usb_hid_report_parser_t *parser); 44 60 45 void dump_standard_interface_descriptor( 46 const usb_standard_interface_descriptor_t *d); 47 48 void dump_standard_endpoint_descriptor( 49 const usb_standard_endpoint_descriptor_t *d); 50 51 void dump_standard_hid_descriptor_header( 52 const usb_standard_hid_descriptor_t *d); 53 54 void dump_standard_hid_class_descriptor_info( 55 const usb_standard_hid_class_descriptor_info_t *d); 56 57 void dump_hid_class_descriptor(int index, uint8_t type, 58 const uint8_t *d, size_t size); 59 60 #endif /* USBHID_DESCDUMP_H_ */ 61 #endif /* LIBUSB_HIDREPORT_H_ */ 61 62 62 63 /** -
uspace/lib/usb/include/usb/classes/hidreq.h
rd8421c4 rf97717d9 27 27 */ 28 28 29 /** @addtogroup drvusbhid29 /** @addtogroup libusb 30 30 * @{ 31 31 */ … … 34 34 */ 35 35 36 #ifndef USB HID_HIDREQ_H_37 #define USB HID_HIDREQ_H_36 #ifndef USB_KBD_HIDREQ_H_ 37 #define USB_KBD_HIDREQ_H_ 38 38 39 39 #include <stdint.h> 40 40 41 41 #include <usb/classes/hid.h> 42 43 #include "hiddev.h" 42 #include <usb/pipes.h> 44 43 45 44 /*----------------------------------------------------------------------------*/ 46 45 47 int usbhid_req_set_report(usb hid_dev_t *hid_dev,46 int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no, 48 47 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size); 49 48 50 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol); 49 int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 50 usb_hid_protocol_t protocol); 51 51 52 int usbhid_req_set_idle(usb hid_dev_t *hid_dev, uint8_t duration);52 int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration); 53 53 54 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 55 uint8_t *buffer, size_t buf_size, size_t *actual_size); 54 int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 55 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 56 size_t *actual_size); 56 57 57 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol); 58 int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 59 usb_hid_protocol_t *protocol); 58 60 59 int usbhid_req_get_idle(usb hid_dev_t *hid_dev, uint8_t *duration);61 int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration); 60 62 61 63 /*----------------------------------------------------------------------------*/ 62 64 63 #endif /* USB HID_HIDREQ_H_ */65 #endif /* USB_KBD_HIDREQ_H_ */ 64 66 65 67 /** -
uspace/lib/usb/include/usb/debug.h
rd8421c4 rf97717d9 79 79 } usb_log_level_t; 80 80 81 /** Default log level. */ 82 #define USB_LOG_LEVEL_DEFAULT USB_LOG_LEVEL_DEBUG 83 81 84 82 85 void usb_log_enable(usb_log_level_t, const char *); -
uspace/lib/usb/include/usb/request.h
rd8421c4 rf97717d9 41 41 #include <usb/pipes.h> 42 42 #include <usb/descriptor.h> 43 44 /** USB device status - device is self powered (opposed to bus powered). */ 45 #define USB_DEVICE_STATUS_SELF_POWERED ((uint16_t)(1 << 0)) 46 47 /** USB device status - remote wake-up signaling is enabled. */ 48 #define USB_DEVICE_STATUS_REMOTE_WAKEUP ((uint16_t)(1 << 1)) 49 50 /** USB endpoint status - endpoint is halted (stalled). */ 51 #define USB_ENDPOINT_STATUS_HALTED ((uint16_t)(1 << 0)) 43 52 44 53 /** Standard device request. */ -
uspace/lib/usb/src/hidparser.c
rd8421c4 rf97717d9 47 47 48 48 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 49 usb_hid_report_item_t *report_item );49 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 50 50 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 51 usb_hid_report_item_t *report_item );51 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 52 52 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 53 usb_hid_report_item_t *report_item );53 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 54 54 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 55 usb_hid_report_item_t *report_item );55 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path); 56 56 57 57 void usb_hid_descriptor_print_list(link_t *head); … … 63 63 int usb_pow(int a, int b); 64 64 65 65 66 int usb_pow(int a, int b) 66 67 { … … 84 85 { 85 86 if(parser == NULL) { 86 return -1;87 return EINVAL; 87 88 } 88 89 … … 110 111 int ret; 111 112 usb_hid_report_item_t *report_item=0; 112 usb_hid_report_item_t *new_report_item; 113 usb_hid_report_item_t *new_report_item; 114 usb_hid_report_path_t *usage_path; 115 usb_hid_report_path_t *tmp_usage_path; 113 116 114 117 size_t offset_input=0; … … 117 120 118 121 122 /* parser structure initialization*/ 123 if(usb_hid_parser_init(parser) != EOK) { 124 return EINVAL; 125 } 126 127 128 /*report item initialization*/ 119 129 if(!(report_item=malloc(sizeof(usb_hid_report_item_t)))){ 120 130 return ENOMEM; 121 131 } 122 132 memset(report_item, 0, sizeof(usb_hid_report_item_t)); 123 124 link_initialize(&(report_item->link)); 125 133 list_initialize(&(report_item->link)); 134 135 /* usage path context initialization */ 136 if(!(usage_path=usb_hid_report_path())){ 137 return ENOMEM; 138 } 139 126 140 while(i<size){ 127 141 if(!USB_HID_ITEM_IS_LONG(data[i])){ 128 142 129 143 if((i+USB_HID_ITEM_SIZE(data[i]))>= size){ 130 return -1; // TODO ERROR CODE144 return EINVAL; // TODO ERROR CODE 131 145 } 132 146 … … 141 155 142 156 ret = usb_hid_report_parse_tag(tag,class,data+i+1, 143 item_size,report_item);157 item_size,report_item, usage_path); 144 158 usb_log_debug2("ret: %u\n", ret); 145 159 switch(ret){ 146 160 case USB_HID_NEW_REPORT_ITEM: 147 161 // store report item to report and create the new one 148 usb_log_debug("\nNEW REPORT ITEM: %X",tag); 162 usb_log_debug("\nNEW REPORT ITEM: %X",ret); 163 164 // store current usage path 165 report_item->usage_path = usage_path; 166 167 // new current usage path 168 tmp_usage_path = usb_hid_report_path(); 169 170 // copy old path to the new one 171 usb_hid_report_path_clone(tmp_usage_path, usage_path); 172 173 // swap 174 usage_path = tmp_usage_path; 175 tmp_usage_path = NULL; 176 149 177 150 178 switch(tag) { … … 184 212 link_initialize(&(new_report_item->link)); 185 213 report_item = new_report_item; 186 214 187 215 break; 188 216 case USB_HID_REPORT_TAG_PUSH: … … 284 312 */ 285 313 int usb_hid_report_parse_tag(uint8_t tag, uint8_t class, const uint8_t *data, size_t item_size, 286 usb_hid_report_item_t *report_item )314 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 287 315 { 288 316 int ret; … … 291 319 case USB_HID_TAG_CLASS_MAIN: 292 320 293 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item )) == EOK) {321 if((ret=usb_hid_report_parse_main_tag(tag,data,item_size,report_item, usage_path)) == EOK) { 294 322 return USB_HID_NEW_REPORT_ITEM; 295 323 } … … 301 329 302 330 case USB_HID_TAG_CLASS_GLOBAL: 303 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item );331 return usb_hid_report_parse_global_tag(tag,data,item_size,report_item, usage_path); 304 332 break; 305 333 306 334 case USB_HID_TAG_CLASS_LOCAL: 307 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item );335 return usb_hid_report_parse_local_tag(tag,data,item_size,report_item, usage_path); 308 336 break; 309 337 default: … … 323 351 324 352 int usb_hid_report_parse_main_tag(uint8_t tag, const uint8_t *data, size_t item_size, 325 usb_hid_report_item_t *report_item )326 { 353 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 354 { 327 355 switch(tag) 328 356 { … … 335 363 336 364 case USB_HID_REPORT_TAG_COLLECTION: 337 // TODO 365 usb_hid_report_path_append_item(usage_path, 0, 0); 366 338 367 return USB_HID_NO_ACTION; 339 368 break; 340 369 341 370 case USB_HID_REPORT_TAG_END_COLLECTION: 342 /* should be ignored */ 371 // TODO 372 // znici posledni uroven ve vsech usage paths 373 // otazka jestli nema nicit dve, respektive novou posledni vynulovat? 374 usb_hid_report_remove_last_item(usage_path); 343 375 return USB_HID_NO_ACTION; 344 376 break; … … 361 393 362 394 int usb_hid_report_parse_global_tag(uint8_t tag, const uint8_t *data, size_t item_size, 363 usb_hid_report_item_t *report_item )395 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 364 396 { 365 397 // TODO take care about the bit length of data … … 367 399 { 368 400 case USB_HID_REPORT_TAG_USAGE_PAGE: 369 report_item->usage_page = usb_hid_report_tag_data_int32(data,item_size); 401 // zmeni to jenom v poslednim poli aktualni usage path 402 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_GLOBAL, 403 usb_hid_report_tag_data_int32(data,item_size)); 370 404 break; 371 405 case USB_HID_REPORT_TAG_LOGICAL_MINIMUM: … … 418 452 */ 419 453 int usb_hid_report_parse_local_tag(uint8_t tag, const uint8_t *data, size_t item_size, 420 usb_hid_report_item_t *report_item )454 usb_hid_report_item_t *report_item, usb_hid_report_path_t *usage_path) 421 455 { 422 456 switch(tag) 423 457 { 424 458 case USB_HID_REPORT_TAG_USAGE: 425 report_item->usage = usb_hid_report_tag_data_int32(data,item_size); 459 usb_hid_report_set_last_item(usage_path, USB_HID_TAG_CLASS_LOCAL, 460 usb_hid_report_tag_data_int32(data,item_size)); 426 461 break; 427 462 case USB_HID_REPORT_TAG_USAGE_MINIMUM: … … 491 526 { 492 527 usb_hid_report_item_t *report_item; 528 usb_hid_report_usage_path_t *path_item; 529 link_t *path; 493 530 link_t *item; 494 531 … … 507 544 usb_log_debug("\tCONSTANT/VAR: %X\n", USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags)); 508 545 usb_log_debug("\tVARIABLE/ARRAY: %X\n", USB_HID_ITEM_FLAG_VARIABLE(report_item->item_flags)); 509 usb_log_debug("\tUSAGE: %X\n", report_item->usage); 510 usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 546 usb_log_debug("\tUSAGE PATH:\n"); 547 548 path = report_item->usage_path->link.next; 549 while(path != &report_item->usage_path->link) { 550 path_item = list_get_instance(path, usb_hid_report_usage_path_t, link); 551 usb_log_debug("\t\tUSAGE PAGE: %X, USAGE: %X\n", path_item->usage_page, path_item->usage); 552 path = path->next; 553 } 554 555 556 // usb_log_debug("\tUSAGE: %X\n", report_item->usage); 557 // usb_log_debug("\tUSAGE PAGE: %X\n", report_item->usage_page); 511 558 usb_log_debug("\tLOGMIN: %X\n", report_item->logical_minimum); 512 559 usb_log_debug("\tLOGMAX: %X\n", report_item->logical_maximum); … … 530 577 void usb_hid_descriptor_print(usb_hid_report_parser_t *parser) 531 578 { 579 if(parser == NULL) { 580 return; 581 } 582 532 583 usb_log_debug("INPUT:\n"); 533 584 usb_hid_descriptor_print_list(&parser->input); … … 561 612 562 613 report_item = list_get_instance(next, usb_hid_report_item_t, link); 614 615 while(!list_empty(&report_item->usage_path->link)) { 616 usb_hid_report_remove_last_item(report_item->usage_path); 617 } 618 619 563 620 next = next->next; 564 621 … … 600 657 int usb_hid_parse_report(const usb_hid_report_parser_t *parser, 601 658 const uint8_t *data, size_t size, 659 usb_hid_report_path_t *path, int flags, 602 660 const usb_hid_report_in_callbacks_t *callbacks, void *arg) 603 661 { … … 615 673 size_t j=0; 616 674 675 if(parser == NULL) { 676 return EINVAL; 677 } 678 679 617 680 // get the size of result keycodes array 618 usb_hid_report_path_t path; 619 path.usage_page = BAD_HACK_USAGE_PAGE; 620 key_count = usb_hid_report_input_length(parser, &path); 681 key_count = usb_hid_report_input_length(parser, path, flags); 621 682 622 683 if(!(keys = malloc(sizeof(uint8_t) * key_count))){ … … 629 690 630 691 item = list_get_instance(list_item, usb_hid_report_item_t, link); 631 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 632 ( item->usage_page == path.usage_page)) {692 if(!USB_HID_ITEM_FLAG_CONSTANT(item->item_flags) && 693 (usb_hid_report_compare_usage_path(item->usage_path, path, flags) == EOK)) { 633 694 for(j=0; j<(size_t)(item->count); j++) { 634 695 if((USB_HID_ITEM_FLAG_VARIABLE(item->item_flags) == 0) || … … 640 701 // bitmapa 641 702 if((item_value = usb_hid_translate_data(item, data, j)) != 0) { 642 keys[i++] = j+ item->usage_minimum;703 keys[i++] = (item->count - 1 - j) + item->usage_minimum; 643 704 } 644 705 else { … … 736 797 737 798 int usb_hid_report_input_length(const usb_hid_report_parser_t *parser, 738 const usb_hid_report_path_t *path)739 { 799 usb_hid_report_path_t *path, int flags) 800 { 740 801 int ret = 0; 741 802 link_t *item; 742 803 usb_hid_report_item_t *report_item; 743 804 805 if(parser == NULL) { 806 return EINVAL; 807 } 808 744 809 item = (&parser->input)->next; 745 810 while(&parser->input != item) { 746 811 report_item = list_get_instance(item, usb_hid_report_item_t, link); 747 812 if(!USB_HID_ITEM_FLAG_CONSTANT(report_item->item_flags) && 748 ( report_item->usage_page == path->usage_page)) {813 (usb_hid_report_compare_usage_path(report_item->usage_path, path, flags) == EOK)) { 749 814 ret += report_item->count; 750 815 } … … 757 822 758 823 824 /** 825 * 826 */ 827 int usb_hid_report_path_append_item(usb_hid_report_path_t *usage_path, 828 int32_t usage_page, int32_t usage) 829 { 830 usb_hid_report_usage_path_t *item; 831 832 if(!(item=malloc(sizeof(usb_hid_report_usage_path_t)))) { 833 return ENOMEM; 834 } 835 list_initialize(&item->link); 836 837 item->usage = usage; 838 item->usage_page = usage_page; 839 840 list_append (&usage_path->link, &item->link); 841 usage_path->depth++; 842 return EOK; 843 } 844 845 /** 846 * 847 */ 848 void usb_hid_report_remove_last_item(usb_hid_report_path_t *usage_path) 849 { 850 usb_hid_report_usage_path_t *item; 851 852 if(!list_empty(&usage_path->link)){ 853 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 854 list_remove(usage_path->link.prev); 855 usage_path->depth--; 856 free(item); 857 } 858 } 859 860 /** 861 * 862 */ 863 void usb_hid_report_null_last_item(usb_hid_report_path_t *usage_path) 864 { 865 usb_hid_report_usage_path_t *item; 866 867 if(!list_empty(&usage_path->link)){ 868 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 869 memset(item, 0, sizeof(usb_hid_report_usage_path_t)); 870 } 871 } 872 873 /** 874 * 875 */ 876 void usb_hid_report_set_last_item(usb_hid_report_path_t *usage_path, int32_t tag, int32_t data) 877 { 878 usb_hid_report_usage_path_t *item; 879 880 if(!list_empty(&usage_path->link)){ 881 item = list_get_instance(usage_path->link.prev, usb_hid_report_usage_path_t, link); 882 883 switch(tag) { 884 case USB_HID_TAG_CLASS_GLOBAL: 885 item->usage_page = data; 886 break; 887 case USB_HID_TAG_CLASS_LOCAL: 888 item->usage = data; 889 break; 890 } 891 } 892 893 } 894 895 /** 896 * 897 */ 898 int usb_hid_report_compare_usage_path(usb_hid_report_path_t *report_path, 899 usb_hid_report_path_t *path, 900 int flags) 901 { 902 usb_hid_report_usage_path_t *report_item; 903 usb_hid_report_usage_path_t *path_item; 904 905 link_t *report_link; 906 link_t *path_link; 907 908 int only_page; 909 910 if(path->depth == 0){ 911 return EOK; 912 } 913 914 915 if((only_page = flags & USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY) != 0){ 916 flags -= USB_HID_PATH_COMPARE_USAGE_PAGE_ONLY; 917 } 918 919 switch(flags){ 920 /* path must be completly identical */ 921 case USB_HID_PATH_COMPARE_STRICT: 922 if(report_path->depth != path->depth){ 923 return 1; 924 } 925 926 report_link = report_path->link.next; 927 path_link = path->link.next; 928 929 while((report_link != &report_path->link) && (path_link != &path->link)) { 930 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 931 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 932 933 if((report_item->usage_page != path_item->usage_page) || 934 ((only_page == 0) && (report_item->usage != path_item->usage))) { 935 return 1; 936 } else { 937 report_link = report_link->next; 938 path_link = path_link->next; 939 } 940 941 } 942 943 if((report_link == &report_path->link) && (path_link == &path->link)) { 944 return EOK; 945 } 946 else { 947 return 1; 948 } 949 break; 950 951 /* given path must be the end of the report one*/ 952 case USB_HID_PATH_COMPARE_END: 953 report_link = report_path->link.prev; 954 path_link = path->link.prev; 955 956 if(list_empty(&path->link)){ 957 return EOK; 958 } 959 960 while((report_link != &report_path->link) && (path_link != &path->link)) { 961 report_item = list_get_instance(report_link, usb_hid_report_usage_path_t, link); 962 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 963 964 if((report_item->usage_page != path_item->usage_page) || 965 ((only_page == 0) && (report_item->usage != path_item->usage))) { 966 return 1; 967 } else { 968 report_link = report_link->prev; 969 path_link = path_link->prev; 970 } 971 972 } 973 974 if(path_link == &path->link) { 975 return EOK; 976 } 977 else { 978 return 1; 979 } 980 981 break; 982 983 default: 984 return EINVAL; 985 } 986 987 988 989 990 } 991 992 /** 993 * 994 */ 995 usb_hid_report_path_t *usb_hid_report_path(void) 996 { 997 usb_hid_report_path_t *path; 998 path = malloc(sizeof(usb_hid_report_path_t)); 999 if(!path){ 1000 return NULL; 1001 } 1002 else { 1003 path->depth = 0; 1004 list_initialize(&path->link); 1005 return path; 1006 } 1007 } 1008 1009 /** 1010 * 1011 */ 1012 void usb_hid_report_path_free(usb_hid_report_path_t *path) 1013 { 1014 while(!list_empty(&path->link)){ 1015 usb_hid_report_remove_last_item(path); 1016 } 1017 } 1018 1019 1020 /** 1021 * 1022 */ 1023 int usb_hid_report_path_clone(usb_hid_report_path_t *new_usage_path, usb_hid_report_path_t *usage_path) 1024 { 1025 usb_hid_report_usage_path_t *path_item; 1026 link_t *path_link; 1027 1028 1029 if(list_empty(&usage_path->link)){ 1030 return EOK; 1031 } 1032 1033 path_link = usage_path->link.next; 1034 while(path_link != &usage_path->link) { 1035 path_item = list_get_instance(path_link, usb_hid_report_usage_path_t, link); 1036 usb_hid_report_path_append_item (new_usage_path, path_item->usage_page, path_item->usage); 1037 1038 path_link = path_link->next; 1039 } 1040 1041 return EOK; 1042 } 1043 759 1044 760 1045 /** -
uspace/lib/usb/src/hidreq.c
rd8421c4 rf97717d9 41 41 #include <usb/debug.h> 42 42 #include <usb/request.h> 43 44 #include "hidreq.h" 45 #include "hiddev.h"43 #include <usb/pipes.h> 44 45 #include <usb/classes/hidreq.h> 46 46 47 47 /*----------------------------------------------------------------------------*/ … … 60 60 * usb_control_request_set(). 61 61 */ 62 int usbhid_req_set_report(usb hid_dev_t *hid_dev,62 int usbhid_req_set_report(usb_pipe_t *ctrl_pipe, int iface_no, 63 63 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size) 64 64 { 65 if (hid_dev == NULL) { 66 usb_log_error("usbhid_req_set_report(): no HID device structure" 67 " given.\n"); 68 return EINVAL; 69 } 70 71 /* 72 * No need for checking other parameters, as they are checked in 73 * the called function (usb_control_request_set()). 74 */ 75 76 int rc, sess_rc; 77 78 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 65 if (ctrl_pipe == NULL) { 66 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 67 return EINVAL; 68 } 69 70 if (iface_no < 0) { 71 usb_log_warning("usbhid_req_set_report(): no interface given." 72 "\n"); 73 return EINVAL; 74 } 75 76 /* 77 * No need for checking other parameters, as they are checked in 78 * the called function (usb_control_request_set()). 79 */ 80 81 int rc, sess_rc; 82 83 sess_rc = usb_pipe_start_session(ctrl_pipe); 79 84 if (sess_rc != EOK) { 80 85 usb_log_warning("Failed to start a session: %s.\n", … … 88 93 usb_log_debug("Sending Set_Report request to the device.\n"); 89 94 90 rc = usb_control_request_set( &hid_dev->ctrl_pipe,91 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 92 USB_HIDREQ_SET_REPORT, value, hid_dev->iface, buffer, buf_size);93 94 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);95 rc = usb_control_request_set(ctrl_pipe, 96 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 97 USB_HIDREQ_SET_REPORT, value, iface_no, buffer, buf_size); 98 99 sess_rc = usb_pipe_end_session(ctrl_pipe); 95 100 96 101 if (rc != EOK) { … … 122 127 * usb_control_request_set(). 123 128 */ 124 int usbhid_req_set_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t protocol) 125 { 126 if (hid_dev == NULL) { 127 usb_log_error("usbhid_req_set_protocol(): no HID device " 128 "structure given.\n"); 129 return EINVAL; 130 } 131 132 /* 133 * No need for checking other parameters, as they are checked in 134 * the called function (usb_control_request_set()). 135 */ 136 137 int rc, sess_rc; 138 139 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 129 int usbhid_req_set_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 130 usb_hid_protocol_t protocol) 131 { 132 if (ctrl_pipe == NULL) { 133 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 134 return EINVAL; 135 } 136 137 if (iface_no < 0) { 138 usb_log_warning("usbhid_req_set_report(): no interface given." 139 "\n"); 140 return EINVAL; 141 } 142 143 /* 144 * No need for checking other parameters, as they are checked in 145 * the called function (usb_control_request_set()). 146 */ 147 148 int rc, sess_rc; 149 150 sess_rc = usb_pipe_start_session(ctrl_pipe); 140 151 if (sess_rc != EOK) { 141 152 usb_log_warning("Failed to start a session: %s.\n", … … 145 156 146 157 usb_log_debug("Sending Set_Protocol request to the device (" 147 "protocol: %d, iface: %d).\n", protocol, hid_dev->iface);148 149 rc = usb_control_request_set( &hid_dev->ctrl_pipe,150 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 151 USB_HIDREQ_SET_PROTOCOL, protocol, hid_dev->iface, NULL, 0);152 153 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);158 "protocol: %d, iface: %d).\n", protocol, iface_no); 159 160 rc = usb_control_request_set(ctrl_pipe, 161 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 162 USB_HIDREQ_SET_PROTOCOL, protocol, iface_no, NULL, 0); 163 164 sess_rc = usb_pipe_end_session(ctrl_pipe); 154 165 155 166 if (rc != EOK) { … … 182 193 * usb_control_request_set(). 183 194 */ 184 int usbhid_req_set_idle(usbhid_dev_t *hid_dev, uint8_t duration) 185 { 186 if (hid_dev == NULL) { 187 usb_log_error("usbhid_req_set_idle(): no HID device " 188 "structure given.\n"); 189 return EINVAL; 190 } 191 192 /* 193 * No need for checking other parameters, as they are checked in 194 * the called function (usb_control_request_set()). 195 */ 196 197 int rc, sess_rc; 198 199 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 195 int usbhid_req_set_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t duration) 196 { 197 if (ctrl_pipe == NULL) { 198 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 199 return EINVAL; 200 } 201 202 if (iface_no < 0) { 203 usb_log_warning("usbhid_req_set_report(): no interface given." 204 "\n"); 205 return EINVAL; 206 } 207 208 /* 209 * No need for checking other parameters, as they are checked in 210 * the called function (usb_control_request_set()). 211 */ 212 213 int rc, sess_rc; 214 215 sess_rc = usb_pipe_start_session(ctrl_pipe); 200 216 if (sess_rc != EOK) { 201 217 usb_log_warning("Failed to start a session: %s.\n", … … 205 221 206 222 usb_log_debug("Sending Set_Idle request to the device (" 207 "duration: %u, iface: %d).\n", duration, hid_dev->iface);223 "duration: %u, iface: %d).\n", duration, iface_no); 208 224 209 225 uint16_t value = duration << 8; 210 226 211 rc = usb_control_request_set( &hid_dev->ctrl_pipe,212 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 213 USB_HIDREQ_SET_IDLE, value, hid_dev->iface, NULL, 0);214 215 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);227 rc = usb_control_request_set(ctrl_pipe, 228 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 229 USB_HIDREQ_SET_IDLE, value, iface_no, NULL, 0); 230 231 sess_rc = usb_pipe_end_session(ctrl_pipe); 216 232 217 233 if (rc != EOK) { … … 247 263 * usb_control_request_set(). 248 264 */ 249 int usbhid_req_get_report(usbhid_dev_t *hid_dev, usb_hid_report_type_t type, 250 uint8_t *buffer, size_t buf_size, size_t *actual_size) 251 { 252 if (hid_dev == NULL) { 253 usb_log_error("usbhid_req_set_report(): no HID device structure" 254 " given.\n"); 255 return EINVAL; 256 } 257 258 /* 259 * No need for checking other parameters, as they are checked in 260 * the called function (usb_control_request_set()). 261 */ 262 263 int rc, sess_rc; 264 265 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 265 int usbhid_req_get_report(usb_pipe_t *ctrl_pipe, int iface_no, 266 usb_hid_report_type_t type, uint8_t *buffer, size_t buf_size, 267 size_t *actual_size) 268 { 269 if (ctrl_pipe == NULL) { 270 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 271 return EINVAL; 272 } 273 274 if (iface_no < 0) { 275 usb_log_warning("usbhid_req_set_report(): no interface given." 276 "\n"); 277 return EINVAL; 278 } 279 280 /* 281 * No need for checking other parameters, as they are checked in 282 * the called function (usb_control_request_set()). 283 */ 284 285 int rc, sess_rc; 286 287 sess_rc = usb_pipe_start_session(ctrl_pipe); 266 288 if (sess_rc != EOK) { 267 289 usb_log_warning("Failed to start a session: %s.\n", … … 275 297 usb_log_debug("Sending Get_Report request to the device.\n"); 276 298 277 rc = usb_control_request_get( &hid_dev->ctrl_pipe,278 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 279 USB_HIDREQ_GET_REPORT, value, hid_dev->iface, buffer, buf_size,299 rc = usb_control_request_get(ctrl_pipe, 300 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 301 USB_HIDREQ_GET_REPORT, value, iface_no, buffer, buf_size, 280 302 actual_size); 281 303 282 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);304 sess_rc = usb_pipe_end_session(ctrl_pipe); 283 305 284 306 if (rc != EOK) { … … 310 332 * usb_control_request_set(). 311 333 */ 312 int usbhid_req_get_protocol(usbhid_dev_t *hid_dev, usb_hid_protocol_t *protocol) 313 { 314 if (hid_dev == NULL) { 315 usb_log_error("usbhid_req_set_protocol(): no HID device " 316 "structure given.\n"); 317 return EINVAL; 318 } 319 320 /* 321 * No need for checking other parameters, as they are checked in 322 * the called function (usb_control_request_set()). 323 */ 324 325 int rc, sess_rc; 326 327 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 334 int usbhid_req_get_protocol(usb_pipe_t *ctrl_pipe, int iface_no, 335 usb_hid_protocol_t *protocol) 336 { 337 if (ctrl_pipe == NULL) { 338 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 339 return EINVAL; 340 } 341 342 if (iface_no < 0) { 343 usb_log_warning("usbhid_req_set_report(): no interface given." 344 "\n"); 345 return EINVAL; 346 } 347 348 /* 349 * No need for checking other parameters, as they are checked in 350 * the called function (usb_control_request_set()). 351 */ 352 353 int rc, sess_rc; 354 355 sess_rc = usb_pipe_start_session(ctrl_pipe); 328 356 if (sess_rc != EOK) { 329 357 usb_log_warning("Failed to start a session: %s.\n", … … 333 361 334 362 usb_log_debug("Sending Get_Protocol request to the device (" 335 "iface: %d).\n", hid_dev->iface);363 "iface: %d).\n", iface_no); 336 364 337 365 uint8_t buffer[1]; 338 366 size_t actual_size = 0; 339 367 340 rc = usb_control_request_get( &hid_dev->ctrl_pipe,341 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 342 USB_HIDREQ_GET_PROTOCOL, 0, hid_dev->iface, buffer, 1, &actual_size);343 344 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);368 rc = usb_control_request_get(ctrl_pipe, 369 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 370 USB_HIDREQ_GET_PROTOCOL, 0, iface_no, buffer, 1, &actual_size); 371 372 sess_rc = usb_pipe_end_session(ctrl_pipe); 345 373 346 374 if (rc != EOK) { … … 381 409 * usb_control_request_set(). 382 410 */ 383 int usbhid_req_get_idle(usbhid_dev_t *hid_dev, uint8_t *duration) 384 { 385 if (hid_dev == NULL) { 386 usb_log_error("usbhid_req_set_idle(): no HID device " 387 "structure given.\n"); 388 return EINVAL; 389 } 390 391 /* 392 * No need for checking other parameters, as they are checked in 393 * the called function (usb_control_request_set()). 394 */ 395 396 int rc, sess_rc; 397 398 sess_rc = usb_pipe_start_session(&hid_dev->ctrl_pipe); 411 int usbhid_req_get_idle(usb_pipe_t *ctrl_pipe, int iface_no, uint8_t *duration) 412 { 413 if (ctrl_pipe == NULL) { 414 usb_log_warning("usbhid_req_set_report(): no pipe given.\n"); 415 return EINVAL; 416 } 417 418 if (iface_no < 0) { 419 usb_log_warning("usbhid_req_set_report(): no interface given." 420 "\n"); 421 return EINVAL; 422 } 423 424 /* 425 * No need for checking other parameters, as they are checked in 426 * the called function (usb_control_request_set()). 427 */ 428 429 int rc, sess_rc; 430 431 sess_rc = usb_pipe_start_session(ctrl_pipe); 399 432 if (sess_rc != EOK) { 400 433 usb_log_warning("Failed to start a session: %s.\n", … … 404 437 405 438 usb_log_debug("Sending Get_Idle request to the device (" 406 "iface: %d).\n", hid_dev->iface);439 "iface: %d).\n", iface_no); 407 440 408 441 uint16_t value = 0; … … 410 443 size_t actual_size = 0; 411 444 412 rc = usb_control_request_get( &hid_dev->ctrl_pipe,413 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 414 USB_HIDREQ_GET_IDLE, value, hid_dev->iface, buffer, 1,445 rc = usb_control_request_get(ctrl_pipe, 446 USB_REQUEST_TYPE_CLASS, USB_REQUEST_RECIPIENT_INTERFACE, 447 USB_HIDREQ_GET_IDLE, value, iface_no, buffer, 1, 415 448 &actual_size); 416 449 417 sess_rc = usb_pipe_end_session( &hid_dev->ctrl_pipe);450 sess_rc = usb_pipe_end_session(ctrl_pipe); 418 451 419 452 if (rc != EOK) { -
uspace/lib/usb/src/host/device_keeper.c
rd8421c4 rf97717d9 214 214 fibril_mutex_lock(&instance->guard); 215 215 216 usb_address_t new_address = instance->last_address + 1; 217 while (instance->devices[new_address].occupied) { 216 usb_address_t new_address = instance->last_address; 217 do { 218 ++new_address; 219 if (new_address > USB11_ADDRESS_MAX) 220 new_address = 1; 218 221 if (new_address == instance->last_address) { 219 222 fibril_mutex_unlock(&instance->guard); 220 223 return ENOSPC; 221 224 } 222 if (new_address == USB11_ADDRESS_MAX) 223 new_address = 1; 224 ++new_address; 225 } 225 } while (instance->devices[new_address].occupied); 226 226 227 227 assert(new_address != USB_ADDRESS_DEFAULT);
Note:
See TracChangeset
for help on using the changeset viewer.