Changeset b724494 in mainline
- Timestamp:
- 2017-10-23T21:26:22Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- ec700c7
- Parents:
- 327f147
- Location:
- uspace/drv/bus/usb/xhci
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/commands.c
r327f147 rb724494 46 46 #define TRB_SET_TCS(trb, tcs) (trb).control |= host2xhci(32, ((tcs &0x1) << 9)) 47 47 #define TRB_SET_TYPE(trb, type) (trb).control |= host2xhci(32, (type) << 10) 48 #define TRB_SET_DC(trb, dc) (trb).control |= host2xhci(32, (dc) << 9) 48 49 #define TRB_SET_EP(trb, ep) (trb).control |= host2xhci(32, ((ep) & 0x5) << 16) 49 50 #define TRB_SET_STREAM(trb, st) (trb).control |= host2xhci(32, ((st) & 0xFFFF) << 16) … … 323 324 assert(hc); 324 325 assert(cmd); 325 assert(ictx); 326 327 xhci_trb_clean(&cmd->trb); 328 329 uint64_t phys_addr = (uint64_t) addr_to_phys(ictx); 330 TRB_SET_ICTX(cmd->trb, phys_addr); 326 327 xhci_trb_clean(&cmd->trb); 328 329 if (!cmd->deconfigure) { 330 /* If the DC flag is on, input context is not evaluated. */ 331 assert(ictx); 332 333 uint64_t phys_addr = (uint64_t) addr_to_phys(ictx); 334 TRB_SET_ICTX(cmd->trb, phys_addr); 335 } 331 336 332 337 TRB_SET_TYPE(cmd->trb, XHCI_TRB_TYPE_CONFIGURE_ENDPOINT_CMD); 333 338 TRB_SET_SLOT(cmd->trb, cmd->slot_id); 339 TRB_SET_DC(cmd->trb, cmd->deconfigure); 334 340 335 341 return enqueue_command(hc, cmd, 0, 0); -
uspace/drv/bus/usb/xhci/commands.h
r327f147 rb724494 58 58 uint32_t slot_id; 59 59 uint32_t status; 60 bool deconfigure; 60 61 61 62 bool completed; -
uspace/drv/bus/usb/xhci/endpoint.c
r327f147 rb724494 242 242 }; 243 243 244 static int create_valid_input_ctx(xhci_input_ctx_t **out_ictx)245 {246 xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t));247 if (!ictx) {248 return ENOMEM;249 }250 251 memset(ictx, 0, sizeof(xhci_input_ctx_t));252 253 // Quoting sec. 4.6.6: A1, D0, D1 are down, A0 is up.254 XHCI_INPUT_CTRL_CTX_ADD_CLEAR(ictx->ctrl_ctx, 1);255 XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 0);256 XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 1);257 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0);258 259 if (out_ictx) {260 *out_ictx = ictx;261 }262 263 return EOK;264 }265 266 244 int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep) 267 245 { … … 300 278 } 301 279 302 /* Issue configure endpoint command (sec 4.3.5). */ 303 xhci_input_ctx_t *ictx; 304 if ((err = create_valid_input_ctx(&ictx))) { 280 /* Add endpoint. */ 281 xhci_ep_ctx_t ep_ctx; 282 memset(&ep_ctx, 0, sizeof(xhci_ep_ctx_t)); 283 setup_ep_ctx_helpers[ep->base.transfer_type](ep, &ep_ctx); 284 285 if ((err = hc_add_endpoint(dev->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx))) { 305 286 goto err_ds; 306 287 } 307 288 308 const unsigned ep_idx = xhci_endpoint_index(ep); 309 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */ 310 setup_ep_ctx_helpers[ep->base.transfer_type](ep, &ictx->endpoint_ctx[ep_idx]); 311 312 xhci_cmd_t cmd; 313 xhci_cmd_init(&cmd); 314 315 cmd.slot_id = dev->slot_id; 316 317 if ((err = xhci_send_configure_endpoint_command(dev->hc, &cmd, ictx))) { 318 goto err_ictx; 319 } 320 321 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) { 322 goto err_ictx; 323 } 324 325 xhci_cmd_fini(&cmd); 326 327 free32(ictx); 328 return EOK; 329 330 err_ictx: 331 free32(ictx); 289 return EOK; 290 332 291 err_ds: 333 292 xhci_endpoint_free_transfer_ds(ep); … … 356 315 } 357 316 358 /* Issue configure endpoint command to drop this endpoint. */ 359 xhci_input_ctx_t *ictx; 360 if ((err = create_valid_input_ctx(&ictx))) { 317 /* Drop the endpoint. */ 318 if ((err = hc_drop_endpoint(dev->hc, dev->slot_id, xhci_endpoint_index(ep)))) { 361 319 goto err; 362 320 } 363 364 const unsigned ep_idx = xhci_endpoint_index(ep);365 XHCI_INPUT_CTRL_CTX_DROP_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */366 367 xhci_cmd_t cmd;368 xhci_cmd_init(&cmd);369 370 cmd.slot_id = dev->slot_id;371 372 if ((err = xhci_send_configure_endpoint_command(dev->hc, &cmd, ictx))) {373 goto err_ictx;374 }375 376 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {377 goto err_ictx;378 }379 380 xhci_cmd_fini(&cmd);381 321 382 322 /* Tear down TRB ring / PSA. */ … … 387 327 */ 388 328 389 free32(ictx); 390 return EOK; 391 392 err_ictx: 393 free32(ictx); 329 return EOK; 330 394 331 err: 395 332 dev->endpoints[ep_num] = ep; … … 403 340 } 404 341 405 int xhci_device_configure(xhci_device_t *dev, xhci_hc_t *hc)406 {407 int err;408 409 /* Issue configure endpoint command (sec 4.3.5). */410 xhci_input_ctx_t *ictx;411 if ((err = create_valid_input_ctx(&ictx))) {412 goto err;413 }414 415 // TODO: Set slot context and other flags. (probably forgot a lot of 'em)416 417 xhci_cmd_t cmd;418 xhci_cmd_init(&cmd);419 420 cmd.slot_id = dev->slot_id;421 422 if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) {423 goto err_cmd;424 }425 426 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) {427 goto err_cmd;428 }429 430 xhci_cmd_fini(&cmd);431 432 free32(ictx);433 return EOK;434 435 err_cmd:436 free32(ictx);437 err:438 return err;439 }440 441 342 /** 442 343 * @} -
uspace/drv/bus/usb/xhci/endpoint.h
r327f147 rb724494 122 122 int xhci_device_remove_endpoint(xhci_device_t *, xhci_endpoint_t *); 123 123 xhci_endpoint_t * xhci_device_get_endpoint(xhci_device_t *, usb_endpoint_t); 124 int xhci_device_configure(xhci_device_t *, xhci_hc_t *);125 124 126 125 static inline xhci_device_t * xhci_device_get(device_t *dev) -
uspace/drv/bus/usb/xhci/hc.c
r327f147 rb724494 652 652 } 653 653 654 static int create_valid_input_ctx(xhci_input_ctx_t **out_ictx) 655 { 656 xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t)); 657 if (!ictx) { 658 return ENOMEM; 659 } 660 661 memset(ictx, 0, sizeof(xhci_input_ctx_t)); 662 663 // Quoting sec. 4.6.6: A1, D0, D1 are down, A0 is up. 664 XHCI_INPUT_CTRL_CTX_ADD_CLEAR(ictx->ctrl_ctx, 1); 665 XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 0); 666 XHCI_INPUT_CTRL_CTX_DROP_CLEAR(ictx->ctrl_ctx, 1); 667 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0); 668 669 if (out_ictx) { 670 *out_ictx = ictx; 671 } 672 673 return EOK; 674 } 675 676 int hc_address_rh_device(xhci_hc_t *hc, uint32_t slot_id, uint8_t port, xhci_ep_ctx_t *ep_ctx) 677 { 678 int err; 679 680 /* Issue configure endpoint command (sec 4.3.5). */ 681 xhci_input_ctx_t *ictx; 682 if ((err = create_valid_input_ctx(&ictx))) { 683 goto err; 684 } 685 686 /* Initialize slot_ctx according to section 4.3.3 point 3. */ 687 XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, port); 688 XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1); 689 690 /* Attaching to root hub port, root string equals to 0. */ 691 XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, 0); 692 693 /* Copy endpoint 0 context and set A1 flag. */ 694 memcpy(&ictx->endpoint_ctx[0], ep_ctx, sizeof(xhci_ep_ctx_t)); 695 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 1); 696 697 if ((err = hc_address_device(hc, slot_id, ictx))) { 698 goto err_cmd; 699 } 700 701 free32(ictx); 702 return EOK; 703 704 err_cmd: 705 free32(ictx); 706 err: 707 return err; 708 } 709 710 int hc_configure_device(xhci_hc_t *hc, uint32_t slot_id) 711 { 712 int err; 713 714 /* Issue configure endpoint command (sec 4.3.5). */ 715 xhci_input_ctx_t *ictx; 716 if ((err = create_valid_input_ctx(&ictx))) { 717 goto err; 718 } 719 720 // TODO: Set slot context and other flags. (probably forgot a lot of 'em) 721 722 xhci_cmd_t cmd; 723 xhci_cmd_init(&cmd); 724 725 cmd.slot_id = slot_id; 726 727 if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) { 728 goto err_cmd; 729 } 730 731 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) { 732 goto err_cmd; 733 } 734 735 xhci_cmd_fini(&cmd); 736 737 free32(ictx); 738 return EOK; 739 740 err_cmd: 741 free32(ictx); 742 err: 743 return err; 744 } 745 746 int hc_deconfigure_device(xhci_hc_t *hc, uint32_t slot_id) 747 { 748 int err; 749 750 /* Issue configure endpoint command (sec 4.3.5) with the DC flag. */ 751 xhci_cmd_t cmd; 752 xhci_cmd_init(&cmd); 753 754 cmd.slot_id = slot_id; 755 cmd.deconfigure = true; 756 757 if ((err = xhci_send_configure_endpoint_command(hc, &cmd, NULL))) { 758 return err; 759 } 760 761 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) { 762 return err; 763 } 764 765 xhci_cmd_fini(&cmd); 766 767 return EOK; 768 } 769 770 int hc_add_endpoint(xhci_hc_t *hc, uint32_t slot_id, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx) 771 { 772 int err; 773 774 /* Issue configure endpoint command (sec 4.3.5). */ 775 xhci_input_ctx_t *ictx; 776 if ((err = create_valid_input_ctx(&ictx))) { 777 goto err; 778 } 779 780 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */ 781 memcpy(&ictx->endpoint_ctx[ep_idx], ep_ctx, sizeof(xhci_ep_ctx_t)); 782 783 // TODO: Set slot context and other flags. (probably forgot a lot of 'em) 784 785 xhci_cmd_t cmd; 786 xhci_cmd_init(&cmd); 787 788 cmd.slot_id = slot_id; 789 790 if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) { 791 goto err_cmd; 792 } 793 794 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) { 795 goto err_cmd; 796 } 797 798 xhci_cmd_fini(&cmd); 799 800 free32(ictx); 801 return EOK; 802 803 err_cmd: 804 free32(ictx); 805 err: 806 return err; 807 } 808 809 int hc_drop_endpoint(xhci_hc_t *hc, uint32_t slot_id, uint8_t ep_idx) 810 { 811 int err; 812 813 /* Issue configure endpoint command (sec 4.3.5). */ 814 xhci_input_ctx_t *ictx; 815 if ((err = create_valid_input_ctx(&ictx))) { 816 goto err; 817 } 818 819 XHCI_INPUT_CTRL_CTX_DROP_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */ 820 821 // TODO: Set slot context and other flags. (probably forgot a lot of 'em) 822 823 xhci_cmd_t cmd; 824 xhci_cmd_init(&cmd); 825 826 cmd.slot_id = slot_id; 827 828 if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) { 829 goto err_cmd; 830 } 831 832 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) { 833 goto err_cmd; 834 } 835 836 xhci_cmd_fini(&cmd); 837 838 free32(ictx); 839 return EOK; 840 841 err_cmd: 842 free32(ictx); 843 err: 844 return err; 845 } 846 654 847 /** 655 848 * @} -
uspace/drv/bus/usb/xhci/hc.h
r327f147 rb724494 96 96 int hc_disable_slot(xhci_hc_t *, uint32_t); 97 97 int hc_address_device(xhci_hc_t *, uint32_t, xhci_input_ctx_t *); 98 int hc_address_rh_device(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *); 99 int hc_configure_device(xhci_hc_t *, uint32_t); 100 int hc_deconfigure_device(xhci_hc_t *, uint32_t); 101 int hc_add_endpoint(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *); 102 int hc_drop_endpoint(xhci_hc_t *, uint32_t, uint8_t); 98 103 99 104 #endif -
uspace/drv/bus/usb/xhci/rh.c
r327f147 rb724494 95 95 { 96 96 int err; 97 98 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port); 97 99 xhci_device_t *xhci_dev = xhci_device_get(dev); 98 99 /* FIXME: Certainly not generic solution. */100 const uint32_t route_str = 0;101 102 100 xhci_dev->hc = rh->hc; 103 104 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port);105 101 xhci_dev->usb3 = speed->major == 3; 106 102 107 /* Enable new slot */103 /* Enable new slot. */ 108 104 if ((err = hc_enable_slot(rh->hc, &xhci_dev->slot_id)) != EOK) 109 105 return err; 110 106 usb_log_debug2("Obtained slot ID: %u.\n", xhci_dev->slot_id); 111 107 112 /* Setup input context */ 113 xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t)); 114 if (!ictx) 115 return ENOMEM; 116 memset(ictx, 0, sizeof(xhci_input_ctx_t)); 117 118 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 0); 119 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 1); 120 121 /* Initialize slot_ctx according to section 4.3.3 point 3. */ 122 /* Attaching to root hub port, root string equals to 0. */ 123 XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, dev->port); 124 XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1); 125 XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, route_str); 126 108 /* Create and configure control endpoint. */ 127 109 endpoint_t *ep0_base = bus_create_endpoint(&rh->hc->bus.base); 128 110 if (!ep0_base) 129 goto err_ictx; 111 return ENOMEM; 112 130 113 xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base); 131 132 /* Control endpoints don't use streams. */133 114 /* FIXME: Sync this with xhci_device_add_endpoint. */ 134 115 ep0->max_streams = 0; 135 116 ep0->max_burst = 0; 136 117 ep0->mult = 0; 118 137 119 if ((err = xhci_endpoint_alloc_transfer_ds(ep0))) 138 goto err_ictx; 139 140 setup_control_ep0_ctx(&ictx->endpoint_ctx[0], &ep0->ring, speed); 120 goto err_ep; 121 122 xhci_ep_ctx_t ep_ctx; 123 memset(&ep_ctx, 0, sizeof(xhci_ep_ctx_t)); 124 setup_control_ep0_ctx(&ep_ctx, &ep0->ring, speed); 141 125 142 126 /* Setup and register device context */ 143 xhci_dev ice_ctx_t *dctx = malloc32(sizeof(xhci_device_ctx_t));144 if (! dctx) {127 xhci_dev->dev_ctx = malloc32(sizeof(xhci_device_ctx_t)); 128 if (!xhci_dev->dev_ctx) { 145 129 err = ENOMEM; 146 goto err_ep; 147 } 148 xhci_dev->dev_ctx = dctx; 149 rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(dctx); 150 memset(dctx, 0, sizeof(xhci_device_ctx_t)); 130 goto err_ds; 131 } 132 rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(xhci_dev->dev_ctx); 133 memset(xhci_dev->dev_ctx, 0, sizeof(xhci_device_ctx_t)); 151 134 152 135 /* Address device */ 153 if ((err = hc_address_ device(rh->hc, xhci_dev->slot_id, ictx)) != EOK)136 if ((err = hc_address_rh_device(rh->hc, xhci_dev->slot_id, dev->port, &ep_ctx))) 154 137 goto err_dctx; 155 dev->address = XHCI_SLOT_DEVICE_ADDRESS( dctx->slot_ctx);138 dev->address = XHCI_SLOT_DEVICE_ADDRESS(xhci_dev->dev_ctx->slot_ctx); 156 139 usb_log_debug2("Obtained USB address: %d.\n", dev->address); 157 140 … … 178 161 } 179 162 180 free32(ictx);181 163 return EOK; 182 164 183 165 err_dctx: 184 free32( dctx);166 free32(xhci_dev->dev_ctx); 185 167 rh->hc->dcbaa[xhci_dev->slot_id] = 0; 168 err_ds: 169 xhci_endpoint_free_transfer_ds(ep0); 186 170 err_ep: 187 171 xhci_endpoint_fini(ep0); 188 172 free(ep0); 189 err_ictx:190 free32(ictx);191 173 return err; 192 174 } … … 316 298 317 299 /* TODO: Figure out how to handle errors here. So far, they are reported and skipped. */ 300 /* TODO: Move parts of the code below to xhci_bus_remove_device() */ 318 301 319 302 /* Make DDF (and all drivers) forget about the device. */ … … 323 306 } 324 307 325 // TODO: Remove EP0. 326 // TODO: Deconfigure device. 308 /* Unregister EP0. */ 309 if ((err = bus_unregister_endpoint(&rh->hc->bus.base, &dev->endpoints[0]->base))) { 310 usb_log_warning("Failed to unregister configuration endpoint of device '%s' from XHCI bus: %s", 311 ddf_fun_get_name(dev->base.fun), str_error(err)); 312 } 313 314 /* Deconfigure device. */ 315 if ((err = hc_deconfigure_device(rh->hc, dev->slot_id))) { 316 usb_log_warning("Failed to deconfigure detached device '%s': %s", 317 ddf_fun_get_name(dev->base.fun), str_error(err)); 318 } 319 320 /* TODO: Free EP0 structures. */ 321 /* TODO: Destroy EP0 by removing its last reference. */ 327 322 328 323 /* Remove device from XHCI bus. */ -
uspace/drv/bus/usb/xhci/transfers.c
r327f147 rb724494 191 191 // Issue a Configure Endpoint command, if needed. 192 192 if (configure_endpoint_needed(setup)) { 193 const int err = xhci_device_configure(xhci_ep_to_dev(xhci_ep), hc);193 const int err = hc_configure_device(hc, xhci_ep_to_dev(xhci_ep)->slot_id); 194 194 if (err) 195 195 return err;
Note:
See TracChangeset
for help on using the changeset viewer.