Changeset 2b61945 in mainline for uspace/drv/bus/usb/xhci/transfers.c
- Timestamp:
- 2017-10-22T03:47:41Z (6 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/transfers.c
r766043c r2b61945 94 94 } 95 95 96 int xhci_init_transfers(xhci_hc_t *hc) 97 { 98 assert(hc); 99 100 list_initialize(&hc->transfers); 101 return EOK; 102 } 103 104 void xhci_fini_transfers(xhci_hc_t *hc) 105 { 106 // Note: Untested. 107 assert(hc); 108 } 109 110 xhci_transfer_t* xhci_transfer_create(endpoint_t* ep) { 111 xhci_transfer_t* transfer = calloc(1, sizeof(xhci_transfer_t)); 112 if (!transfer) 113 return NULL; 96 /** 97 * There can currently be only one active transfer, because 98 * usb_transfer_batch_init locks the endpoint by endpoint_use. 99 * Therefore, we store the only active transfer per endpoint there. 100 */ 101 xhci_transfer_t* xhci_transfer_create(endpoint_t* ep) 102 { 103 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep); 104 xhci_transfer_t *transfer = &xhci_ep->active_transfer; 105 106 /* Do not access the transfer yet, it may be still in use. */ 114 107 115 108 usb_transfer_batch_init(&transfer->batch, ep); 116 117 link_initialize(&transfer->link); 109 assert(ep->active); 110 111 /* Clean just our data. */ 112 memset(((void *) transfer) + sizeof(usb_transfer_batch_t), 0, 113 sizeof(xhci_transfer_t) - sizeof(usb_transfer_batch_t)); 118 114 119 115 return transfer; … … 126 122 if (transfer->hc_buffer) 127 123 free32(transfer->hc_buffer); 128 129 free(transfer);130 124 } 131 125 132 126 static xhci_trb_ring_t *get_ring(xhci_hc_t *hc, xhci_transfer_t *transfer) 133 127 { 134 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep); 135 uint8_t slot_id = xhci_ep->device->slot_id; 136 137 xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[transfer->batch.ep->target.endpoint]; 138 assert(ring); 139 return ring; 128 return &xhci_endpoint_get(transfer->batch.ep)->ring; 140 129 } 141 130 … … 202 191 // Issue a Configure Endpoint command, if needed. 203 192 if (configure_endpoint_needed(setup)) { 204 const int err = xhci_device_configure(xhci_ep ->device, hc);193 const int err = xhci_device_configure(xhci_ep_to_dev(xhci_ep), hc); 205 194 if (err) 206 195 return err; … … 226 215 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 227 216 228 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep); 229 uint8_t slot_id = xhci_ep->device->slot_id; 230 xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[transfer->batch.ep->target.endpoint]; 217 xhci_trb_ring_t* ring = get_ring(hc, transfer); 231 218 232 219 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); … … 249 236 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 250 237 251 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(transfer->batch.ep); 252 uint8_t slot_id = xhci_ep->device->slot_id; 253 xhci_trb_ring_t* ring = hc->dcbaa_virt[slot_id].trs[transfer->batch.ep->target.endpoint]; 238 xhci_trb_ring_t* ring = get_ring(hc, transfer); 254 239 255 240 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); … … 266 251 { 267 252 uintptr_t addr = trb->parameter; 268 xhci_transfer_t *transfer = NULL; 269 270 link_t *transfer_link = list_first(&hc->transfers); 271 while (transfer_link) { 272 transfer = list_get_instance(transfer_link, xhci_transfer_t, link); 273 274 if (transfer->interrupt_trb_phys == addr) 275 break; 276 277 transfer_link = list_next(transfer_link, &hc->transfers); 278 } 279 280 if (!transfer_link) { 281 usb_log_warning("Transfer not found."); 253 const unsigned slot_id = XHCI_DWORD_EXTRACT(trb->control, 31, 24); 254 const unsigned ep_dci = XHCI_DWORD_EXTRACT(trb->control, 20, 16); 255 256 xhci_device_t *dev = hc->bus.devices_by_slot[slot_id]; 257 if (!dev) { 258 usb_log_error("Transfer event on unknown device slot %u!", slot_id); 282 259 return ENOENT; 283 260 } 284 261 285 list_remove(transfer_link); 262 const usb_endpoint_t ep_num = ep_dci / 2; 263 xhci_endpoint_t *ep = xhci_device_get_endpoint(dev, ep_num); 264 if (!ep) { 265 usb_log_error("Transfer event on unknown endpoint num %u, device slot %u!", ep_num, slot_id); 266 return ENOENT; 267 } 268 269 xhci_transfer_t *transfer = &ep->active_transfer; 270 271 /** FIXME: This is racy. Do we care? */ 272 ep->ring.dequeue = addr; 273 286 274 usb_transfer_batch_t *batch = &transfer->batch; 287 275 … … 314 302 xhci_transfer_t *transfer = xhci_transfer_from_batch(batch); 315 303 xhci_endpoint_t *xhci_ep = xhci_endpoint_get(batch->ep); 316 uint8_t slot_id = xhci_ep->device->slot_id;317 318 304 assert(xhci_ep); 319 assert(slot_id);320 305 321 306 const usb_transfer_type_t type = batch->ep->transfer_type; … … 336 321 return err; 337 322 338 list_append(&transfer->link, &hc->transfers); 339 323 const uint8_t slot_id = xhci_ep_to_dev(xhci_ep)->slot_id; 340 324 const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */ 341 325 return hc_ring_doorbell(hc, slot_id, target);
Note:
See TracChangeset
for help on using the changeset viewer.