Changeset eb928c4 in mainline for uspace/drv/bus/usb/xhci/commands.c
- Timestamp:
- 2018-01-08T00:07:00Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 1102eca
- Parents:
- ecbad17
- git-author:
- Ondřej Hlavatý <aearsis@…> (2018-01-08 00:05:39)
- git-committer:
- Ondřej Hlavatý <aearsis@…> (2018-01-08 00:07:00)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/commands.c
recbad17 reb928c4 70 70 } 71 71 72 /** 73 * Initialize the command subsystem. Allocates the comand ring. 74 * 75 * Does not configure the CR pointer to the hardware, because the xHC will be 76 * reset before starting. 77 */ 72 78 int xhci_init_commands(xhci_hc_t *hc) 73 79 { … … 89 95 } 90 96 97 /** 98 * Finish the command subsystem. Stops the hardware from running commands, then 99 * deallocates the ring. 100 */ 91 101 void xhci_fini_commands(xhci_hc_t *hc) 92 102 { 103 assert(hc); 93 104 xhci_stop_command_ring(hc); 94 assert(hc); 95 } 96 105 106 xhci_cmd_ring_t *cr = get_cmd_ring(hc); 107 108 fibril_mutex_lock(&cr->guard); 109 xhci_trb_ring_fini(&cr->trb_ring); 110 fibril_mutex_unlock(&cr->guard); 111 } 112 113 /** 114 * Initialize a command structure for the given command. 115 */ 97 116 void xhci_cmd_init(xhci_cmd_t *cmd, xhci_cmd_type_t type) 98 117 { … … 107 126 } 108 127 128 /** 129 * Finish the command structure. Some command invocation includes allocating 130 * a context structure. To have the convenience in calling commands, this 131 * method deallocates all resources. 132 */ 109 133 void xhci_cmd_fini(xhci_cmd_t *cmd) 110 134 { … … 119 143 } 120 144 121 /** Call with guard locked. */ 145 /** 146 * Find a command issued by TRB at @c phys inside the command list. 147 * 148 * Call with guard locked only. 149 */ 122 150 static inline xhci_cmd_t *find_command(xhci_hc_t *hc, uint64_t phys) 123 151 { … … 140 168 } 141 169 142 static inline int enqueue_command(xhci_hc_t *hc, xhci_cmd_t *cmd, unsigned doorbell, unsigned target) 170 /** 171 * Enqueue a command on the TRB ring. Ring the doorbell to initiate processing. 172 * Register the command as waiting for completion inside the command list. 173 */ 174 static inline int enqueue_command(xhci_hc_t *hc, xhci_cmd_t *cmd) 143 175 { 144 176 xhci_cmd_ring_t *cr = get_cmd_ring(hc); … … 168 200 } 169 201 202 /** 203 * Stop the command ring. Stop processing commands, block issuing new ones. 204 * Wait until hardware acknowledges it is stopped. 205 */ 170 206 void xhci_stop_command_ring(xhci_hc_t *hc) 171 207 { … … 187 223 } 188 224 225 /** 226 * Abort currently processed command. Note that it is only aborted when the 227 * command is "blocking" - see section 4.6.1.2 of xHCI spec. 228 */ 189 229 static void abort_command_ring(xhci_hc_t *hc) 190 230 { … … 236 276 }; 237 277 278 /** 279 * Report an error according to command completion code. 280 */ 238 281 static void report_error(int code) 239 282 { … … 244 287 } 245 288 289 /** 290 * Handle a command completion. Feed the fibril waiting for result. 291 * 292 * @param trb The COMMAND_COMPLETION TRB found in event ring. 293 */ 246 294 int xhci_handle_command_completion(xhci_hc_t *hc, xhci_trb_t *trb) 247 295 { … … 343 391 TRB_SET_TYPE(cmd->_header.trb, XHCI_TRB_TYPE_NO_OP_CMD); 344 392 345 return enqueue_command(hc, cmd , 0, 0);393 return enqueue_command(hc, cmd); 346 394 } 347 395 … … 355 403 cmd->_header.trb.control |= host2xhci(32, XHCI_REG_RD(hc->xecp, XHCI_EC_SP_SLOT_TYPE) << 16); 356 404 357 return enqueue_command(hc, cmd , 0, 0);405 return enqueue_command(hc, cmd); 358 406 } 359 407 … … 368 416 TRB_SET_SLOT(cmd->_header.trb, cmd->slot_id); 369 417 370 return enqueue_command(hc, cmd , 0, 0);418 return enqueue_command(hc, cmd); 371 419 } 372 420 … … 398 446 TRB_SET_SLOT(cmd->_header.trb, cmd->slot_id); 399 447 400 return enqueue_command(hc, cmd , 0, 0);448 return enqueue_command(hc, cmd); 401 449 } 402 450 … … 419 467 TRB_SET_DC(cmd->_header.trb, cmd->deconfigure); 420 468 421 return enqueue_command(hc, cmd , 0, 0);469 return enqueue_command(hc, cmd); 422 470 } 423 471 … … 441 489 TRB_SET_SLOT(cmd->_header.trb, cmd->slot_id); 442 490 443 return enqueue_command(hc, cmd , 0, 0);491 return enqueue_command(hc, cmd); 444 492 } 445 493 … … 460 508 TRB_SET_SLOT(cmd->_header.trb, cmd->slot_id); 461 509 462 return enqueue_command(hc, cmd , 0, 0);510 return enqueue_command(hc, cmd); 463 511 } 464 512 … … 475 523 TRB_SET_SLOT(cmd->_header.trb, cmd->slot_id); 476 524 477 return enqueue_command(hc, cmd , 0, 0);525 return enqueue_command(hc, cmd); 478 526 } 479 527 … … 495 543 */ 496 544 497 return enqueue_command(hc, cmd , 0, 0);545 return enqueue_command(hc, cmd); 498 546 } 499 547 … … 508 556 TRB_SET_SLOT(cmd->_header.trb, cmd->slot_id); 509 557 510 return enqueue_command(hc, cmd , 0, 0);558 return enqueue_command(hc, cmd); 511 559 } 512 560 … … 524 572 TRB_SET_DEV_SPEED(cmd->_header.trb, cmd->device_speed); 525 573 526 return enqueue_command(hc, cmd , 0, 0);574 return enqueue_command(hc, cmd); 527 575 } 528 576 … … 541 589 [XHCI_CMD_SET_TR_DEQUEUE_POINTER] = set_tr_dequeue_pointer_cmd, 542 590 [XHCI_CMD_RESET_DEVICE] = reset_device_cmd, 543 // TODO: Force event (optional normative, for VMM, section 4.6.12).544 591 [XHCI_CMD_FORCE_EVENT] = NULL, 545 // TODO: Negotiate bandwidth (optional normative, section 4.6.13).546 592 [XHCI_CMD_NEGOTIATE_BANDWIDTH] = NULL, 547 // TODO: Set latency tolerance value (optional normative, section 4.6.14).548 593 [XHCI_CMD_SET_LATENCY_TOLERANCE_VALUE] = NULL, 549 // TODO: Get port bandwidth (mandatory, but needs root hub implementation, section 4.6.15).550 594 [XHCI_CMD_GET_PORT_BANDWIDTH] = get_port_bandwidth_cmd, 551 // TODO: Force header (mandatory, but needs root hub implementation, section 4.6.16).552 595 [XHCI_CMD_FORCE_HEADER] = NULL, 553 596 [XHCI_CMD_NO_OP] = no_op_cmd 554 597 }; 555 598 599 /** 600 * Try to abort currently processed command. This is tricky, because 601 * calling fibril is not necessarily the one which issued the blocked command. 602 * Also, the trickiness intensifies by the fact that stopping a CR is denoted by 603 * event, which is again handled in different fibril. but, once we go to sleep 604 * on waiting for that event, another fibril may wake up and try to abort the 605 * blocked command. 606 * 607 * So, we mark the command ring as being restarted, wait for it to stop, and 608 * then start it again. If there was a blocked command, it will be satisfied by 609 * COMMAND_ABORTED event. 610 */ 556 611 static int try_abort_current_command(xhci_hc_t *hc) 557 612 { … … 603 658 } 604 659 660 /** 661 * Wait, until the command is completed. The completion is triggered by 662 * COMMAND_COMPLETION event. As we do not want to rely on HW completing the 663 * command in timely manner, we timeout. Note that we can't just return an 664 * error after the timeout pass - it may be other command blocking the ring, 665 * and ours can be completed afterwards. Therefore, it is not guaranteed that 666 * this function will return in XHCI_COMMAND_TIMEOUT. It will continue waiting 667 * until COMMAND_COMPLETION event arrives. 668 */ 605 669 static int wait_for_cmd_completion(xhci_hc_t *hc, xhci_cmd_t *cmd) 606 670 { … … 630 694 } 631 695 632 /** Issue command and block the current fibril until it is completed or timeout 633 * expires. Nothing is deallocated. Caller should always execute `xhci_cmd_fini`. 696 /** 697 * Issue command and block the current fibril until it is completed or timeout 698 * expires. Nothing is deallocated. Caller should always execute `xhci_cmd_fini`. 634 699 */ 635 700 int xhci_cmd_sync(xhci_hc_t *hc, xhci_cmd_t *cmd) … … 658 723 } 659 724 660 /** Does the same thing as `xhci_cmd_sync` and executes `xhci_cmd_fini`. This 661 * is a useful shorthand for issuing commands without out parameters. 725 /** 726 * Does the same thing as `xhci_cmd_sync` and executes `xhci_cmd_fini`. This 727 * is a useful shorthand for issuing commands without out parameters. 662 728 */ 663 729 int xhci_cmd_sync_fini(xhci_hc_t *hc, xhci_cmd_t *cmd) … … 669 735 } 670 736 671 /** Does the same thing as `xhci_cmd_sync_fini` without blocking the current 672 * fibril. The command is copied to stack memory and `fini` is called upon its completion. 737 /** 738 * Does the same thing as `xhci_cmd_sync_fini` without blocking the current 739 * fibril. The command is copied to stack memory and `fini` is called upon its completion. 673 740 */ 674 741 int xhci_cmd_async_fini(xhci_hc_t *hc, xhci_cmd_t *stack_cmd)
Note:
See TracChangeset
for help on using the changeset viewer.