Changeset 47e9494 in mainline for uspace/drv/bus/usb/xhci/transfers.c
- Timestamp:
- 2018-01-16T18:02:46Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- eeca8a6
- Parents:
- 7d1dd2b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/drv/bus/usb/xhci/transfers.c
r7d1dd2b r47e9494 39 39 #include "hc.h" 40 40 #include "hw_struct/trb.h" 41 #include "streams.h" 41 42 #include "transfers.h" 42 43 #include "trb_ring.h" … … 121 122 static xhci_trb_ring_t *get_ring(xhci_hc_t *hc, xhci_transfer_t *transfer) 122 123 { 123 return &xhci_endpoint_get(transfer->batch.ep)->ring; 124 xhci_endpoint_t *ep = xhci_endpoint_get(transfer->batch.ep); 125 if (ep->primary_stream_data_size == 0) return &ep->ring; 126 uint32_t stream_id = transfer->batch.target.stream; 127 128 xhci_stream_data_t *stream_data = xhci_get_stream_ctx_data(ep, stream_id); 129 if (stream_data == NULL) { 130 usb_log_warning("No transfer ring was found for stream %u.", stream_id); 131 return NULL; 132 } 133 134 return &stream_data->ring; 124 135 } 125 136 … … 202 213 // data size (sent for OUT, or buffer size) 203 214 TRB_CTRL_SET_XFER_LEN(trb, transfer->batch.buffer_size); 204 // FIXME: TD size 4.11.2.4 205 TRB_CTRL_SET_TD_SIZE(trb, 1); 206 207 // we want an interrupt after this td is done 208 TRB_CTRL_SET_IOC(trb, 1); 209 210 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 211 212 xhci_trb_ring_t* ring = get_ring(hc, transfer); 213 214 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 215 216 /* The stream-enabled endpoints need to chain ED trb */ 217 xhci_endpoint_t *ep = xhci_endpoint_get(transfer->batch.ep); 218 if (!ep->primary_stream_data_size) { 219 // FIXME: TD size 4.11.2.4 220 TRB_CTRL_SET_TD_SIZE(trb, 1); 221 222 // we want an interrupt after this td is done 223 TRB_CTRL_SET_IOC(trb, 1); 224 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 225 226 xhci_trb_ring_t* ring = get_ring(hc, transfer); 227 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 228 } 229 else { 230 TRB_CTRL_SET_TD_SIZE(trb, 2); 231 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_NORMAL); 232 TRB_CTRL_SET_CHAIN(trb, 1); 233 TRB_CTRL_SET_ENT(trb, 1); 234 235 xhci_trb_ring_t* ring = get_ring(hc, transfer); 236 int err = xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 237 238 if (err) { 239 return err; 240 } 241 242 xhci_trb_clean(&trb); 243 trb.parameter = host2xhci(64, (uintptr_t) transfer); 244 TRB_CTRL_SET_TRB_TYPE(trb, XHCI_TRB_TYPE_EVENT_DATA); 245 TRB_CTRL_SET_IOC(trb, 1); 246 247 return xhci_trb_ring_enqueue(ring, &trb, &transfer->interrupt_trb_phys); 248 } 215 249 } 216 250 … … 267 301 xhci_endpoint_t *ep = xhci_endpoint_get(ep_base); 268 302 269 xhci_trb_ring_update_dequeue(&ep->ring, addr); 270 271 if (ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) { 272 isoch_handle_transfer_event(hc, ep, trb); 273 endpoint_del_ref(&ep->base); 274 return EOK; 275 } 276 277 fibril_mutex_lock(&ep->base.guard); 278 usb_transfer_batch_t *batch = ep->base.active_batch; 279 if (!batch) { 303 usb_transfer_batch_t *batch; 304 xhci_transfer_t *transfer; 305 306 if (TRB_EVENT_DATA(*trb)) { 307 assert(ep->base.transfer_type != USB_TRANSFER_ISOCHRONOUS); 308 /* We are received transfer pointer instead - work with that */ 309 transfer = (xhci_transfer_t *) addr; 310 xhci_trb_ring_t * ring = get_ring(hc, transfer); 311 xhci_trb_ring_update_dequeue(ring, transfer->interrupt_trb_phys); 312 batch = &transfer->batch; 313 314 fibril_mutex_lock(&ep->base.guard); 315 endpoint_deactivate_locked(&ep->base); 280 316 fibril_mutex_unlock(&ep->base.guard); 281 endpoint_del_ref(&ep->base); 282 return ENOENT; 317 } 318 else { 319 xhci_trb_ring_update_dequeue(&ep->ring, addr); 320 321 if (ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) { 322 isoch_handle_transfer_event(hc, ep, trb); 323 endpoint_del_ref(&ep->base); 324 return EOK; 325 } 326 327 fibril_mutex_lock(&ep->base.guard); 328 batch = ep->base.active_batch; 329 if (!batch) { 330 fibril_mutex_unlock(&ep->base.guard); 331 endpoint_del_ref(&ep->base); 332 return ENOENT; 333 } 334 335 transfer = xhci_transfer_from_batch(batch); 336 337 endpoint_deactivate_locked(&ep->base); 338 fibril_mutex_unlock(&ep->base.guard); 283 339 } 284 340 … … 296 352 } 297 353 298 endpoint_deactivate_locked(&ep->base);299 fibril_mutex_unlock(&ep->base.guard);300 301 xhci_transfer_t *transfer = xhci_transfer_from_batch(batch);302 303 354 if (batch->dir == USB_DIRECTION_IN) { 304 355 assert(batch->buffer); … … 370 421 371 422 const uint8_t slot_id = xhci_dev->slot_id; 372 const uint8_t target = xhci_endpoint_index(xhci_ep) + 1; /* EP Doorbells start at 1 */ 423 /* EP Doorbells start at 1 */ 424 const uint8_t target = (xhci_endpoint_index(xhci_ep) + 1) | (batch->target.stream << 16); 373 425 hc_ring_doorbell(hc, slot_id, target); 374 426 return EOK;
Note:
See TracChangeset
for help on using the changeset viewer.