Changeset 2b61945 in mainline for uspace/drv/bus/usb/xhci/rh.c
- Timestamp:
- 2017-10-22T03:47:41Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 2e5aea1
- Parents:
- 766043c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/rh.c
r766043c r2b61945 92 92 } 93 93 94 // TODO: Check device deallocation, we free device_ctx in hc.c, not95 // sure about the other structs.96 94 // TODO: This currently assumes the device is attached to rh directly. 97 95 // Also, we should consider moving a lot of functionailty to xhci bus 98 96 int xhci_rh_address_device(xhci_rh_t *rh, device_t *dev, xhci_bus_t *bus) 99 97 { 98 int err; 99 xhci_device_t *xhci_dev = xhci_device_get(dev); 100 100 101 /* FIXME: Certainly not generic solution. */ 101 102 const uint32_t route_str = 0; 102 103 103 int err;104 xhci_hc_t *hc = rh->hc; 104 xhci_dev->hc = rh->hc; 105 105 106 const xhci_port_speed_t *speed = xhci_rh_get_port_speed(rh, dev->port); 107 xhci_dev->usb3 = speed->major == 3; 106 108 107 109 /* Enable new slot */ 108 uint32_t slot_id; 109 if ((err = hc_enable_slot(hc, &slot_id)) != EOK) 110 if ((err = hc_enable_slot(rh->hc, &xhci_dev->slot_id)) != EOK) 110 111 return err; 111 usb_log_debug2("Obtained slot ID: %u.\n", slot_id);112 usb_log_debug2("Obtained slot ID: %u.\n", xhci_dev->slot_id); 112 113 113 114 /* Setup input context */ 114 xhci_input_ctx_t *ictx = malloc (sizeof(xhci_input_ctx_t));115 xhci_input_ctx_t *ictx = malloc32(sizeof(xhci_input_ctx_t)); 115 116 if (!ictx) 116 117 return ENOMEM; … … 126 127 XHCI_SLOT_ROUTE_STRING_SET(ictx->slot_ctx, route_str); 127 128 128 xhci_trb_ring_t *ep_ring = malloc(sizeof(xhci_trb_ring_t)); 129 if (!ep_ring) { 130 err = ENOMEM; 129 endpoint_t *ep0_base = bus_create_endpoint(&rh->hc->bus.base); 130 if (!ep0_base) 131 131 goto err_ictx; 132 } 133 134 err = xhci_trb_ring_init(ep_ring); 135 if (err) 136 goto err_ring; 137 setup_control_ep0_ctx(&ictx->endpoint_ctx[0], ep_ring, speed); 132 xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base); 133 setup_control_ep0_ctx(&ictx->endpoint_ctx[0], &ep0->ring, speed); 138 134 139 135 /* Setup and register device context */ … … 141 137 if (!dctx) { 142 138 err = ENOMEM; 143 goto err_ring; 144 } 139 goto err_ep; 140 } 141 xhci_dev->dev_ctx = dctx; 142 rh->hc->dcbaa[xhci_dev->slot_id] = addr_to_phys(dctx); 145 143 memset(dctx, 0, sizeof(xhci_device_ctx_t)); 146 hc->dcbaa[slot_id] = addr_to_phys(dctx);147 148 memset(&hc->dcbaa_virt[slot_id], 0, sizeof(xhci_virt_device_ctx_t));149 hc->dcbaa_virt[slot_id].dev_ctx = dctx;150 hc->dcbaa_virt[slot_id].trs[0] = ep_ring;151 144 152 145 /* Address device */ 153 if ((err = hc_address_device( hc,slot_id, ictx)) != EOK)146 if ((err = hc_address_device(rh->hc, xhci_dev->slot_id, ictx)) != EOK) 154 147 goto err_dctx; 155 148 dev->address = XHCI_SLOT_DEVICE_ADDRESS(dctx->slot_ctx); 156 149 usb_log_debug2("Obtained USB address: %d.\n", dev->address); 157 150 158 // Ask libusbhost to create a control endpoint for EP0. 159 bus_t *bus_base = &bus->base; 160 usb_target_t ep0_target = { .address = dev->address, .endpoint = 0 }; 161 usb_direction_t ep0_direction = USB_DIRECTION_BOTH; 162 163 // TODO: Should this call be unified with other calls to `bus_add_ep()`? 164 err = bus_add_ep(bus_base, dev, ep0_target.endpoint, ep0_direction, 165 USB_TRANSFER_CONTROL, CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1); 166 167 if (err != EOK) 168 goto err_add_ep; 169 170 // Save all data structures in the corresponding xhci_device_t. 171 endpoint_t *ep0_base = bus_find_endpoint(bus_base, ep0_target, ep0_direction); 172 xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base); 173 xhci_device_t *xhci_dev = ep0->device; 174 175 xhci_dev->device = dev; 176 xhci_dev->slot_id = slot_id; 177 xhci_dev->usb3 = speed->major == 3; 178 xhci_dev->hc = hc; 151 // XXX: Going around bus, duplicating code 152 ep0_base->device = dev; 153 ep0_base->target.address = dev->address; 154 ep0_base->target.endpoint = 0; 155 ep0_base->direction = USB_DIRECTION_BOTH; 156 ep0_base->transfer_type = USB_TRANSFER_CONTROL; 157 ep0_base->max_packet_size = CTRL_PIPE_MIN_PACKET_SIZE; 158 ep0_base->packets = 1; 159 ep0_base->bandwidth = CTRL_PIPE_MIN_PACKET_SIZE; 160 161 bus_register_endpoint(&rh->hc->bus.base, ep0_base); 179 162 180 163 if (!rh->devices[dev->port - 1]) { … … 183 166 } 184 167 185 return EOK;186 187 err_add_ep: 168 free32(ictx); 169 return EOK; 170 188 171 err_dctx: 189 if (dctx) { 190 free(dctx); 191 hc->dcbaa[slot_id] = 0; 192 memset(&hc->dcbaa_virt[slot_id], 0, sizeof(xhci_virt_device_ctx_t)); 193 } 194 err_ring: 195 if (ep_ring) { 196 xhci_trb_ring_fini(ep_ring); 197 free(ep_ring); 198 } 172 free32(dctx); 173 rh->hc->dcbaa[xhci_dev->slot_id] = 0; 174 err_ep: 175 xhci_endpoint_fini(ep0); 176 free(ep0); 199 177 err_ictx: 200 free (ictx);178 free32(ictx); 201 179 return err; 202 180 }
Note:
See TracChangeset
for help on using the changeset viewer.