Changeset 0206d35 in mainline for uspace/drv/bus/usb/xhci/rh.c
- Timestamp:
- 2017-10-25T00:03:57Z (8 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c3d926f3
- Parents:
- 56db65d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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));
Note:
See TracChangeset
for help on using the changeset viewer.