Changeset 0206d35 in mainline
- Timestamp:
- 2017-10-25T00:03:57Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c3d926f3
- Parents:
- 56db65d
- Location:
- uspace
- Files:
-
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/bus.c
r56db65d r0206d35 49 49 #include "transfers.h" 50 50 51 /** TODO: Still some copy-pasta left... 52 */ 51 52 /* FIXME Are these really static? Older HCs fetch it from descriptor. */ 53 /* FIXME Add USB3 options, if applicable. */ 54 static const usb_endpoint_desc_t ep0_desc = { 55 .endpoint_no = 0, 56 .direction = USB_DIRECTION_BOTH, 57 .transfer_type = USB_TRANSFER_CONTROL, 58 .max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE, 59 .packets = 1, 60 }; 61 62 static int prepare_endpoint(xhci_endpoint_t *ep, const usb_endpoint_desc_t *desc) 63 { 64 /* Extract information from endpoint_desc */ 65 ep->base.target = (usb_target_t) {{ 66 .address = ep->base.device->address, 67 .endpoint = desc->endpoint_no, 68 }}; 69 ep->base.direction = desc->direction; 70 ep->base.transfer_type = desc->transfer_type; 71 ep->base.max_packet_size = desc->max_packet_size; 72 ep->base.packets = desc->packets; 73 ep->max_streams = desc->usb3.max_streams; 74 ep->max_burst = desc->usb3.max_burst; 75 // TODO add this property to usb_endpoint_desc_t and fetch it from ss companion desc 76 ep->mult = 0; 77 78 return xhci_endpoint_alloc_transfer_ds(ep); 79 } 80 81 static endpoint_t *create_endpoint(bus_t *base); 82 83 static int address_device(xhci_hc_t *hc, xhci_device_t *dev) 84 { 85 int err; 86 87 /* Enable new slot. */ 88 if ((err = hc_enable_slot(hc, &dev->slot_id)) != EOK) 89 return err; 90 usb_log_debug2("Obtained slot ID: %u.\n", dev->slot_id); 91 92 /* Create and configure control endpoint. */ 93 endpoint_t *ep0_base = create_endpoint(&hc->bus.base); 94 if (!ep0_base) 95 goto err_slot; 96 97 /* Temporary reference */ 98 endpoint_add_ref(ep0_base); 99 100 ep0_base->device = &dev->base; 101 xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base); 102 103 if ((err = prepare_endpoint(ep0, &ep0_desc))) 104 goto err_ep; 105 106 /* Address device */ 107 if ((err = hc_address_device(hc, dev, ep0))) 108 goto err_prepared_ep; 109 110 /* Register EP0, passing Temporary reference */ 111 ep0->base.target.address = dev->base.address; 112 dev->endpoints[0] = ep0; 113 114 return EOK; 115 116 err_prepared_ep: 117 xhci_endpoint_free_transfer_ds(ep0); 118 err_ep: 119 endpoint_del_ref(ep0_base); 120 err_slot: 121 hc_disable_slot(hc, dev->slot_id); 122 return err; 123 } 124 53 125 int xhci_bus_enumerate_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev) 54 126 { 55 127 int err; 56 128 xhci_device_t *xhci_dev = xhci_device_get(dev); 57 58 /* TODO: get speed from the default address reservation */59 dev->speed = USB_SPEED_FULL;60 129 61 130 /* Manage TT */ … … 72 141 73 142 /* Assign an address to the device */ 74 if ((err = xhci_rh_address_device(&hc->rh, dev, bus))) {143 if ((err = address_device(hc, xhci_dev))) { 75 144 usb_log_error("Failed to setup address of the new device: %s", str_error(err)); 76 145 return err; 77 146 } 147 148 // TODO: Fetch descriptor of EP0 and reconfigure it accordingly 149 assert(xhci_dev->endpoints[0]); 78 150 79 151 assert(bus->devices_by_slot[xhci_dev->slot_id] == NULL); … … 93 165 } 94 166 167 static int unregister_endpoint(bus_t *, endpoint_t *); 168 95 169 int xhci_bus_remove_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev) 96 170 { … … 98 172 99 173 /* Unregister remaining endpoints. */ 100 for ( size_ti = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) {174 for (unsigned i = 0; i < ARRAY_SIZE(xhci_dev->endpoints); ++i) { 101 175 if (!xhci_dev->endpoints[i]) 102 176 continue; 103 177 104 // FIXME: ignoring return code 105 bus_unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base); 178 const int err = unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base); 179 if (err) 180 usb_log_warning("Failed to unregister EP (%u:%u): %s", dev->address, i, str_error(err)); 106 181 } 107 182 … … 167 242 static int register_endpoint(bus_t *bus_base, endpoint_t *ep, const usb_endpoint_desc_t *desc) 168 243 { 244 int err; 169 245 xhci_bus_t *bus = bus_to_xhci_bus(bus_base); 170 246 assert(bus); 171 247 172 248 assert(ep->device); 173 174 /* Extract USB2-related information from endpoint_desc */175 ep->target = (usb_target_t) {{176 .address = ep->device->address,177 .endpoint = desc->endpoint_no,178 }};179 ep->direction = desc->direction;180 ep->transfer_type = desc->transfer_type;181 ep->max_packet_size = desc->max_packet_size;182 ep->packets = desc->packets;183 249 184 250 xhci_device_t *xhci_dev = xhci_device_get(ep->device); 185 251 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep); 186 252 187 xhci_ep->max_streams = desc->usb3.max_streams; 188 xhci_ep->max_burst = desc->usb3.max_burst; 189 // TODO add this property to usb_endpoint_desc_t and fetch it from ss companion desc 190 xhci_ep->mult = 0; 253 if ((err = prepare_endpoint(xhci_ep, desc))) 254 return err; 191 255 192 256 usb_log_info("Endpoint(%d:%d) registered to XHCI bus.", ep->target.address, ep->target.endpoint); -
uspace/drv/bus/usb/xhci/endpoint.c
r56db65d r0206d35 197 197 static void setup_control_ep_ctx(xhci_endpoint_t *ep, xhci_ep_ctx_t *ctx) 198 198 { 199 // EP0 is configured elsewhere.200 assert(ep->base.target.endpoint > 0);201 202 199 XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(ep)); 203 200 XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, ep->base.max_packet_size); 201 XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst); 202 XHCI_EP_MULT_SET(*ctx, ep->mult); 204 203 XHCI_EP_ERROR_COUNT_SET(*ctx, 3); 205 204 XHCI_EP_TR_DPTR_SET(*ctx, ep->ring.dequeue); … … 211 210 XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(ep)); 212 211 XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, ep->base.max_packet_size); 213 XHCI_EP_MAX_BURST_SIZE_SET(*ctx, 214 xhci_device_get(ep->base.device)->usb3 ? ep->max_burst : 0); 212 XHCI_EP_MAX_BURST_SIZE_SET(*ctx, ep->max_burst); 215 213 XHCI_EP_ERROR_COUNT_SET(*ctx, 3); 216 214 … … 260 258 }; 261 259 260 void xhci_setup_endpoint_context(xhci_endpoint_t *ep, xhci_ep_ctx_t *ep_ctx) 261 { 262 assert(ep); 263 assert(ep_ctx); 264 265 usb_transfer_type_t tt = ep->base.transfer_type; 266 assert(tt < ARRAY_SIZE(setup_ep_ctx_helpers)); 267 268 memset(ep_ctx, 0, sizeof(*ep_ctx)); 269 setup_ep_ctx_helpers[tt](ep, ep_ctx); 270 } 271 262 272 int xhci_device_add_endpoint(xhci_device_t *dev, xhci_endpoint_t *ep) 263 273 { … … 270 280 } 271 281 272 int err = ENOMEM;273 282 const usb_endpoint_t ep_num = ep->base.target.endpoint; 274 283 … … 288 297 } 289 298 290 /* Set up TRB ring / PSA. */291 if ((err = xhci_endpoint_alloc_transfer_ds(ep))) {292 goto err;293 }294 295 299 /* Add endpoint. */ 296 300 xhci_ep_ctx_t ep_ctx; 297 memset(&ep_ctx, 0, sizeof(xhci_ep_ctx_t)); 298 setup_ep_ctx_helpers[ep->base.transfer_type](ep, &ep_ctx); 299 300 if ((err = hc_add_endpoint(dev->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx))) { 301 goto err_ds; 302 } 303 304 return EOK; 305 306 err_ds: 307 xhci_endpoint_free_transfer_ds(ep); 308 err: 309 dev->endpoints[ep_num] = NULL; 310 dev->active_endpoint_count--; 311 return err; 301 xhci_setup_endpoint_context(ep, &ep_ctx); 302 303 return hc_add_endpoint(dev->hc, dev->slot_id, xhci_endpoint_index(ep), &ep_ctx); 312 304 } 313 305 -
uspace/drv/bus/usb/xhci/endpoint.h
r56db65d r0206d35 119 119 uint8_t xhci_endpoint_index(xhci_endpoint_t *); 120 120 121 void xhci_setup_endpoint_context(xhci_endpoint_t *, xhci_ep_ctx_t *); 122 121 123 int xhci_device_add_endpoint(xhci_device_t *, xhci_endpoint_t *); 122 124 int xhci_device_remove_endpoint(xhci_device_t *, xhci_endpoint_t *); -
uspace/drv/bus/usb/xhci/hc.c
r56db65d r0206d35 43 43 #include "rh.h" 44 44 #include "hw_struct/trb.h" 45 #include "hw_struct/context.h" 46 #include "endpoint.h" 45 47 #include "commands.h" 46 48 #include "transfers.h" … … 449 451 { 450 452 assert(batch); 453 assert(batch->ep); 451 454 452 455 usb_log_debug2("Endpoint(%d:%d) started %s transfer of size %lu.", … … 632 635 } 633 636 634 int hc_address_device(xhci_hc_t *hc, uint32_t slot_id, xhci_input_ctx_t *ictx)635 {636 assert(hc);637 638 int err;639 xhci_cmd_t cmd;640 xhci_cmd_init(&cmd);641 642 cmd.slot_id = slot_id;643 644 if ((err = xhci_send_address_device_command(hc, &cmd, ictx)) != EOK)645 return err;646 647 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT)) != EOK)648 return err;649 650 xhci_cmd_fini(&cmd);651 return EOK;652 }653 654 637 static int create_valid_input_ctx(xhci_input_ctx_t **out_ictx) 655 638 { … … 674 657 } 675 658 676 int hc_address_rh_device(xhci_hc_t *hc, uint32_t slot_id, uint8_t port, xhci_ep_ctx_t *ep_ctx) 659 // TODO: This currently assumes the device is attached to rh directly 660 // -> calculate route string 661 int hc_address_device(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *ep0) 662 { 663 int err = ENOMEM; 664 665 /* Setup and register device context */ 666 dev->dev_ctx = malloc32(sizeof(xhci_device_ctx_t)); 667 if (!dev->dev_ctx) 668 goto err; 669 memset(dev->dev_ctx, 0, sizeof(xhci_device_ctx_t)); 670 671 hc->dcbaa[dev->slot_id] = addr_to_phys(dev->dev_ctx); 672 673 /* Issue configure endpoint command (sec 4.3.5). */ 674 xhci_input_ctx_t *ictx; 675 if ((err = create_valid_input_ctx(&ictx))) { 676 goto err_dev_ctx; 677 } 678 679 /* Initialize slot_ctx according to section 4.3.3 point 3. */ 680 XHCI_SLOT_ROOT_HUB_PORT_SET(ictx->slot_ctx, dev->base.port); // FIXME: This should be port at RH 681 XHCI_SLOT_CTX_ENTRIES_SET(ictx->slot_ctx, 1); 682 683 /* Attaching to root hub port, root string equals to 0. */ 684 XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, 0); // FIXME: This is apparently valid in limited cases 685 686 /* Copy endpoint 0 context and set A1 flag. */ 687 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, 1); 688 xhci_setup_endpoint_context(ep0, &ictx->endpoint_ctx[0]); 689 690 xhci_cmd_t cmd; 691 xhci_cmd_init(&cmd); 692 693 cmd.slot_id = dev->slot_id; 694 695 if ((err = xhci_send_address_device_command(hc, &cmd, ictx)) != EOK) 696 goto err_cmd; 697 698 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT)) != EOK) 699 goto err_cmd; 700 701 dev->base.address = XHCI_SLOT_DEVICE_ADDRESS(dev->dev_ctx->slot_ctx); 702 usb_log_debug2("Obtained USB address: %d.\n", dev->base.address); 703 704 /* From now on, the device is officially online, yay! */ 705 fibril_mutex_lock(&dev->base.guard); 706 dev->online = true; 707 fibril_mutex_unlock(&dev->base.guard); 708 709 xhci_cmd_fini(&cmd); 710 free32(ictx); 711 return EOK; 712 713 err_cmd: 714 xhci_cmd_fini(&cmd); 715 free32(ictx); 716 err_dev_ctx: 717 free32(dev->dev_ctx); 718 hc->dcbaa[dev->slot_id] = 0; 719 err: 720 return err; 721 } 722 723 int hc_configure_device(xhci_hc_t *hc, uint32_t slot_id) 677 724 { 678 725 int err; … … 684 731 } 685 732 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))) { 733 // TODO: Set slot context and other flags. (probably forgot a lot of 'em) 734 735 xhci_cmd_t cmd; 736 xhci_cmd_init(&cmd); 737 738 cmd.slot_id = slot_id; 739 740 if ((err = xhci_send_configure_endpoint_command(hc, &cmd, ictx))) { 698 741 goto err_cmd; 699 742 } 743 744 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) { 745 goto err_cmd; 746 } 747 748 xhci_cmd_fini(&cmd); 700 749 701 750 free32(ictx); … … 708 757 } 709 758 710 int hc_configure_device(xhci_hc_t *hc, uint32_t slot_id) 759 int hc_deconfigure_device(xhci_hc_t *hc, uint32_t slot_id) 760 { 761 int err; 762 763 /* Issue configure endpoint command (sec 4.3.5) with the DC flag. */ 764 xhci_cmd_t cmd; 765 xhci_cmd_init(&cmd); 766 767 cmd.slot_id = slot_id; 768 cmd.deconfigure = true; 769 770 if ((err = xhci_send_configure_endpoint_command(hc, &cmd, NULL))) { 771 return err; 772 } 773 774 if ((err = xhci_cmd_wait(&cmd, XHCI_DEFAULT_TIMEOUT))) { 775 return err; 776 } 777 778 xhci_cmd_fini(&cmd); 779 780 return EOK; 781 } 782 783 int hc_add_endpoint(xhci_hc_t *hc, uint32_t slot_id, uint8_t ep_idx, xhci_ep_ctx_t *ep_ctx) 711 784 { 712 785 int err; … … 718 791 } 719 792 793 XHCI_INPUT_CTRL_CTX_ADD_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */ 794 memcpy(&ictx->endpoint_ctx[ep_idx], ep_ctx, sizeof(xhci_ep_ctx_t)); 795 720 796 // TODO: Set slot context and other flags. (probably forgot a lot of 'em) 721 797 … … 744 820 } 745 821 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) 822 int hc_drop_endpoint(xhci_hc_t *hc, uint32_t slot_id, uint8_t ep_idx) 771 823 { 772 824 int err; … … 778 830 } 779 831 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)); 832 XHCI_INPUT_CTRL_CTX_DROP_SET(ictx->ctrl_ctx, ep_idx + 1); /* Preceded by slot ctx */ 782 833 783 834 // TODO: Set slot context and other flags. (probably forgot a lot of 'em) … … 807 858 } 808 859 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 847 860 /** 848 861 * @} -
uspace/drv/bus/usb/xhci/hc.h
r56db65d r0206d35 83 83 } xhci_hc_t; 84 84 85 typedef struct xhci_endpoint xhci_endpoint_t; 86 typedef struct xhci_device xhci_device_t; 87 85 88 int hc_init_mmio(xhci_hc_t *, const hw_res_list_parsed_t *); 86 89 int hc_init_memory(xhci_hc_t *, ddf_dev_t *); … … 95 98 int hc_enable_slot(xhci_hc_t *, uint32_t *); 96 99 int hc_disable_slot(xhci_hc_t *, uint32_t); 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 *); 100 int hc_address_device(xhci_hc_t *, xhci_device_t *, xhci_endpoint_t *); 99 101 int hc_configure_device(xhci_hc_t *, uint32_t); 100 102 int hc_deconfigure_device(xhci_hc_t *, uint32_t); -
uspace/drv/bus/usb/xhci/rh.c
r56db65d r0206d35 74 74 } 75 75 76 static void setup_control_ep0_ctx(xhci_ep_ctx_t *ctx, xhci_trb_ring_t *ring, 77 const xhci_port_speed_t *speed) 78 { 79 XHCI_EP_TYPE_SET(*ctx, EP_TYPE_CONTROL); 80 // TODO: must be changed with a command after USB descriptor is read 81 // See 4.6.5 in XHCI specification, first note 82 XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, speed->major == 3 ? 512 : 8); 83 XHCI_EP_MAX_BURST_SIZE_SET(*ctx, 0); 84 XHCI_EP_TR_DPTR_SET(*ctx, ring->dequeue); 85 XHCI_EP_DCS_SET(*ctx, 1); 86 XHCI_EP_INTERVAL_SET(*ctx, 0); 87 XHCI_EP_MAX_P_STREAMS_SET(*ctx, 0); 88 XHCI_EP_MULT_SET(*ctx, 0); 89 XHCI_EP_ERROR_COUNT_SET(*ctx, 3); 90 } 91 92 /* FIXME Are these really static? Older HCs fetch it from descriptor. */ 93 /* FIXME Add USB3 options, if applicable. */ 94 static const usb_endpoint_desc_t ep0_desc = { 95 .endpoint_no = 0, 96 .direction = USB_DIRECTION_BOTH, 97 .transfer_type = USB_TRANSFER_CONTROL, 98 .max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE, 99 .packets = 1, 100 }; 101 102 // TODO: This currently assumes the device is attached to rh directly. 103 // Also, we should consider moving a lot of functionailty to xhci bus 104 int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev, xhci_bus_t *bus) 105 { 106 int err; 107 108 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port); 109 xhci_device_t *xhci_dev = xhci_device_get(dev); 110 xhci_dev->hc = rh->hc; 111 xhci_dev->usb3 = speed->major == 3; 112 113 /* Enable new slot. */ 114 if ((err = hc_enable_slot(rh->hc, &xhci_dev->slot_id)) != EOK) 115 return err; 116 usb_log_debug2("Obtained slot ID: %u.\n", xhci_dev->slot_id); 117 118 /* Create and configure control endpoint. */ 119 endpoint_t *ep0_base = bus_create_endpoint(&rh->hc->bus.base); 120 if (!ep0_base) 121 return ENOMEM; 122 123 xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base); 124 125 if ((err = xhci_endpoint_alloc_transfer_ds(ep0))) 126 goto err_ep; 127 128 xhci_ep_ctx_t ep_ctx; 129 memset(&ep_ctx, 0, sizeof(xhci_ep_ctx_t)); 130 setup_control_ep0_ctx(&ep_ctx, &ep0->ring, speed); 131 132 /* Setup and register device context */ 133 xhci_dev->dev_ctx = malloc32(sizeof(xhci_device_ctx_t)); 134 if (!xhci_dev->dev_ctx) { 135 err = ENOMEM; 136 goto err_ds; 137 } 138 rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(xhci_dev->dev_ctx); 139 memset(xhci_dev->dev_ctx, 0, sizeof(xhci_device_ctx_t)); 140 141 /* Address device */ 142 if ((err = hc_address_rh_device(rh->hc, xhci_dev->slot_id, dev->port, &ep_ctx))) 143 goto err_dctx; 144 dev->address = XHCI_SLOT_DEVICE_ADDRESS(xhci_dev->dev_ctx->slot_ctx); 145 usb_log_debug2("Obtained USB address: %d.\n", dev->address); 146 147 /* From now on, the device is officially online, yay! */ 148 fibril_mutex_lock(&dev->guard); 149 xhci_dev->online = true; 150 fibril_mutex_unlock(&dev->guard); 151 152 ep0_base->device = dev; 153 154 bus_register_endpoint(&rh->hc->bus.base, ep0_base, &ep0_desc); 155 156 if (!rh->devices[dev->port - 1]) { 157 /* Only save the device if it's the first one connected to this port. */ 158 rh->devices[dev->port - 1] = xhci_dev; 159 } 160 161 return EOK; 162 163 err_dctx: 164 free32(xhci_dev->dev_ctx); 165 rh->hc->dcbaa[xhci_dev->slot_id] = 0; 166 err_ds: 167 xhci_endpoint_free_transfer_ds(ep0); 168 err_ep: 169 xhci_endpoint_fini(ep0); 170 free(ep0); 171 return err; 76 static usb_speed_t port_speed_to_usb_speed(const xhci_port_speed_t *port_speed) 77 { 78 assert(port_speed->major > 0 && port_speed->major <= USB_SPEED_SUPER); 79 80 switch (port_speed->major) { 81 case 3: return USB_SPEED_SUPER; 82 case 2: return USB_SPEED_HIGH; 83 case 1: return port_speed->minor ? USB_SPEED_FULL : USB_SPEED_LOW; 84 } 85 86 assert(false); 172 87 } 173 88 … … 188 103 } 189 104 105 const xhci_port_speed_t *port_speed = xhci_rh_get_port_speed(rh, port_id); 106 xhci_device_t *xhci_dev = xhci_device_get(dev); 107 xhci_dev->hc = rh->hc; 108 xhci_dev->usb3 = port_speed->major == 3; 109 190 110 dev->hub = &rh->device; 191 111 dev->port = port_id; 112 dev->speed = port_speed_to_usb_speed(port_speed); 192 113 193 114 if ((err = xhci_bus_enumerate_device(bus, rh->hc, dev))) { … … 207 128 fibril_mutex_lock(&rh->device.guard); 208 129 list_append(&dev->link, &rh->device.devices); 130 if (!rh->devices[port_id - 1]) { 131 /* Only save the device if it's the first one connected to this port. */ 132 rh->devices[port_id - 1] = xhci_dev; 133 } 209 134 fibril_mutex_unlock(&rh->device.guard); 210 135 … … 286 211 continue; 287 212 213 /* FIXME: This is racy. */ 288 214 if ((err = xhci_transfer_abort(&ep->active_transfer))) { 289 215 usb_log_warning("Failed to abort active %s transfer to " … … 305 231 306 232 /* Unregister EP0. */ 307 if ((err = bus_ unregister_endpoint(&rh->hc->bus.base, &dev->endpoints[0]->base))) {233 if ((err = bus_remove_endpoint(&rh->hc->bus.base, &dev->endpoints[0]->base))) { 308 234 usb_log_warning("Failed to unregister configuration endpoint of device '%s' from XHCI bus: %s", 309 235 ddf_fun_get_name(dev->base.fun), str_error(err)); -
uspace/lib/usbhost/include/usb/host/bus.h
r56db65d r0206d35 117 117 int device_init(device_t *); 118 118 119 extern int bus_add_ep(bus_t *, device_t *, const usb_endpoint_desc_t *);120 extern int bus_remove_ep(bus_t *, device_t *, usb_target_t, usb_direction_t);121 122 119 int device_set_default_name(device_t *); 123 120 … … 125 122 int bus_remove_device(bus_t *, hcd_t *, device_t *); 126 123 127 endpoint_t *bus_create_endpoint(bus_t *); 128 int bus_register_endpoint(bus_t *, endpoint_t *, const usb_endpoint_desc_t *); 129 int bus_unregister_endpoint(bus_t *, endpoint_t *); 124 int bus_add_endpoint(bus_t *, device_t *, const usb_endpoint_desc_t *, endpoint_t **); 130 125 endpoint_t *bus_find_endpoint(bus_t *, device_t *, usb_target_t, usb_direction_t); 126 int bus_remove_endpoint(bus_t *, endpoint_t *); 131 127 132 128 size_t bus_count_bw(endpoint_t *, size_t); -
uspace/lib/usbhost/src/bus.c
r56db65d r0206d35 66 66 } 67 67 68 int bus_add_ep(bus_t *bus, device_t *device, const usb_endpoint_desc_t *desc)69 {70 assert(bus);71 assert(device);72 73 /* Temporary reference */74 endpoint_t *ep = bus_create_endpoint(bus);75 if (!ep)76 return ENOMEM;77 78 ep->device = device;79 const int err = bus_register_endpoint(bus, ep, desc);80 81 /* drop Temporary reference */82 endpoint_del_ref(ep);83 84 return err;85 }86 87 int bus_remove_ep(bus_t *bus, device_t *dev, usb_target_t target, usb_direction_t dir)88 {89 assert(bus);90 endpoint_t *ep = bus_find_endpoint(bus, dev, target, dir);91 if (!ep)92 return ENOENT;93 94 return bus_unregister_endpoint(bus, ep);95 }96 97 68 int device_set_default_name(device_t *dev) 98 69 { … … 136 107 } 137 108 138 endpoint_t *bus_create_endpoint(bus_t *bus) 139 { 140 assert(bus); 141 142 fibril_mutex_lock(&bus->guard); 109 int bus_add_endpoint(bus_t *bus, device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep) 110 { 111 int err = ENOMEM; 112 113 assert(bus); 114 assert(device); 115 116 fibril_mutex_lock(&bus->guard); 117 143 118 endpoint_t *ep = bus->ops.create_endpoint(bus); 144 if (ep) { 145 /* Exporting reference */ 146 endpoint_add_ref(ep); 147 } 148 fibril_mutex_unlock(&bus->guard); 149 150 return ep; 151 } 152 153 int bus_register_endpoint(bus_t *bus, endpoint_t *ep, const usb_endpoint_desc_t *desc) 154 { 155 assert(bus); 156 assert(ep); 119 if (!ep) 120 goto err; 157 121 158 122 /* Bus reference */ 159 123 endpoint_add_ref(ep); 160 124 161 fibril_mutex_lock(&bus->guard); 162 const int r = bus->ops.register_endpoint(bus, ep, desc); 163 fibril_mutex_unlock(&bus->guard); 164 165 return r; 166 } 167 168 int bus_unregister_endpoint(bus_t *bus, endpoint_t *ep) 169 { 170 assert(bus); 171 assert(ep); 172 173 fibril_mutex_lock(&bus->guard); 174 const int r = bus->ops.unregister_endpoint(bus, ep); 175 fibril_mutex_unlock(&bus->guard); 176 177 if (r) 178 return r; 179 180 /* Bus reference */ 125 ep->device = device; 126 if ((err = bus->ops.register_endpoint(bus, ep, desc))) 127 goto err_ep; 128 129 if (out_ep) { 130 endpoint_add_ref(ep); 131 *out_ep = ep; 132 } 133 134 fibril_mutex_unlock(&bus->guard); 135 return EOK; 136 137 err_ep: 181 138 endpoint_del_ref(ep); 182 183 return EOK; 139 err: 140 fibril_mutex_unlock(&bus->guard); 141 return err; 184 142 } 185 143 … … 201 159 } 202 160 161 int bus_remove_endpoint(bus_t *bus, endpoint_t *ep) 162 { 163 assert(bus); 164 assert(ep); 165 166 fibril_mutex_lock(&bus->guard); 167 const int r = bus->ops.unregister_endpoint(bus, ep); 168 fibril_mutex_unlock(&bus->guard); 169 170 if (r) 171 return r; 172 173 /* Bus reference */ 174 endpoint_del_ref(ep); 175 176 return EOK; 177 } 178 203 179 int bus_request_address(bus_t *bus, usb_address_t *hint, bool strict, usb_speed_t speed) 204 180 { -
uspace/lib/usbhost/src/ddf_helpers.c
r56db65d r0206d35 104 104 endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval); 105 105 106 return bus_add_e p(hcd->bus, dev, endpoint_desc);106 return bus_add_endpoint(hcd->bus, dev, endpoint_desc, NULL); 107 107 } 108 108 … … 130 130 dev->address, endpoint_desc->endpoint_no, 131 131 usb_str_direction(endpoint_desc->direction)); 132 return bus_remove_ep(hcd->bus, dev, target, endpoint_desc->direction); 132 133 endpoint_t *ep = bus_find_endpoint(hcd->bus, dev, target, endpoint_desc->direction); 134 if (!ep) 135 return ENOENT; 136 137 return bus_remove_endpoint(hcd->bus, ep); 133 138 } 134 139 -
uspace/lib/usbhost/src/usb2_bus.c
r56db65d r0206d35 120 120 /* Add default pipe on default address */ 121 121 usb_log_debug("Device(%d): Adding default target (0:0)", address); 122 err = bus_add_ep(bus, dev, &usb2_default_control_ep); 122 123 endpoint_t *default_ep; 124 err = bus_add_endpoint(bus, dev, &usb2_default_control_ep, &default_ep); 123 125 if (err != EOK) { 124 126 usb_log_error("Device(%d): Failed to add default target: %s.", … … 169 171 /* Register EP on the new address */ 170 172 usb_log_debug("Device(%d): Registering control EP.", address); 171 err = bus_add_e p(bus, dev, &control_ep);173 err = bus_add_endpoint(bus, dev, &control_ep, NULL); 172 174 if (err != EOK) { 173 175 usb_log_error("Device(%d): Failed to register EP0: %s", … … 176 178 } 177 179 178 bus_remove_ep(bus, dev, usb2_default_target, USB_DIRECTION_BOTH); 180 err = bus_remove_endpoint(bus, default_ep); 181 assert(err == EOK); 182 endpoint_del_ref(default_ep); 183 184 err = bus_release_address(bus, address); 185 assert(err == EOK); 186 179 187 return EOK; 180 188 181 189 err_default_control_ep: 182 bus_remove_ep(bus, dev, usb2_default_target, USB_DIRECTION_BOTH); 190 bus_remove_endpoint(bus, default_ep); 191 endpoint_del_ref(default_ep); 183 192 err_address: 184 193 bus_release_address(bus, address);
Note:
See TracChangeset
for help on using the changeset viewer.