1// Copyright 2018 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include <ddk/debug.h> 6#include <string.h> 7 8#include "xhci-transfer-common.h" 9 10void xhci_print_trb(xhci_transfer_ring_t* ring, xhci_trb_t* trb) { 11 int index = trb - ring->start; 12 uint32_t* ptr = (uint32_t *)trb; 13 uint64_t paddr = io_buffer_phys(&ring->buffer) + index * sizeof(xhci_trb_t); 14 15 zxlogf(LSPEW, "trb[%03d] %p: %08X %08X %08X %08X\n", index, (void *)paddr, ptr[0], ptr[1], ptr[2], ptr[3]); 16} 17 18void xhci_transfer_state_init(xhci_transfer_state_t* state, usb_request_t* req, 19 uint8_t ep_type, uint16_t ep_max_packet_size) { 20 memset(state, 0, sizeof(*state)); 21 22 // compute number of packets needed for this transaction 23 if (req->header.length > 0) { 24 usb_request_phys_iter_init(&state->phys_iter, req, XHCI_MAX_DATA_BUFFER); 25 zx_paddr_t dummy_paddr; 26 while (usb_request_phys_iter_next(&state->phys_iter, &dummy_paddr) > 0) { 27 state->packet_count++; 28 } 29 } 30 31 usb_request_phys_iter_init(&state->phys_iter, req, XHCI_MAX_DATA_BUFFER); 32 33 usb_setup_t* setup = (req->header.ep_address == 0 ? &req->setup : NULL); 34 if (setup) { 35 state->direction = setup->bmRequestType & USB_ENDPOINT_DIR_MASK; 36 state->needs_status = true; 37 } else { 38 state->direction = req->header.ep_address & USB_ENDPOINT_DIR_MASK; 39 } 40 state->needs_data_event = true; 41 // Zero length bulk transfers are allowed. We should have at least one transfer TRB 42 // to avoid consecutive event data TRBs on a transfer ring. 43 // See XHCI spec, section 4.11.5.2 44 state->needs_transfer_trb = ep_type == USB_ENDPOINT_BULK; 45 46 // send zero length packet if send_zlp is set and transfer is a multiple of max packet size 47 state->needs_zlp = req->header.send_zlp && (req->header.length % ep_max_packet_size) == 0; 48} 49 50zx_status_t xhci_queue_data_trbs(xhci_transfer_ring_t* ring, xhci_transfer_state_t* state, 51 usb_request_t* req, int interrupter_target, bool isochronous) { 52 usb_header_t* header = &req->header; 53 uint64_t frame = header->frame; 54 size_t free_trbs = xhci_transfer_ring_free_trbs(ring); 55 56 zx_paddr_t paddr; 57 size_t transfer_size = 0; 58 bool first_packet = (state->phys_iter.offset == 0); 59 while (free_trbs > 0 && (((transfer_size = usb_request_phys_iter_next(&state->phys_iter, &paddr)) > 0) || 60 state->needs_transfer_trb || state->needs_zlp)) { 61 xhci_trb_t* trb = ring->current; 62 xhci_clear_trb(trb); 63 XHCI_WRITE64(&trb->ptr, paddr); 64 XHCI_SET_BITS32(&trb->status, XFER_TRB_XFER_LENGTH_START, XFER_TRB_XFER_LENGTH_BITS, 65 transfer_size); 66 // number of packets remaining after this one 67 uint32_t td_size = --state->packet_count; 68 if (state->needs_zlp) { 69 td_size++; 70 } 71 XHCI_SET_BITS32(&trb->status, XFER_TRB_TD_SIZE_START, XFER_TRB_TD_SIZE_BITS, td_size); 72 XHCI_SET_BITS32(&trb->status, XFER_TRB_INTR_TARGET_START, XFER_TRB_INTR_TARGET_BITS, 73 interrupter_target); 74 uint32_t control_bits = TRB_CHAIN; 75 if (td_size == 0) { 76 control_bits |= XFER_TRB_ENT; 77 } 78 if (header->ep_address == 0 && first_packet) { 79 // use TRB_TRANSFER_DATA for first data packet on setup requests 80 control_bits |= (state->direction == USB_DIR_IN ? XFER_TRB_DIR_IN : XFER_TRB_DIR_OUT); 81 trb_set_control(trb, TRB_TRANSFER_DATA, control_bits); 82 } else if (isochronous && first_packet) { 83 // use TRB_TRANSFER_ISOCH for first data packet on isochronous endpoints 84 if (frame == 0) { 85 // set SIA bit to schedule packet ASAP 86 control_bits |= XFER_TRB_SIA; 87 } else { 88 // schedule packet for specified frame 89 control_bits |= (((frame % 2048) << XFER_TRB_FRAME_ID_START) & 90 XHCI_MASK(XFER_TRB_FRAME_ID_START, XFER_TRB_FRAME_ID_BITS)); 91 } 92 trb_set_control(trb, TRB_TRANSFER_ISOCH, control_bits); 93 } else { 94 trb_set_control(trb, TRB_TRANSFER_NORMAL, control_bits); 95 } 96 if (driver_get_log_flags() & DDK_LOG_SPEW) xhci_print_trb(ring, trb); 97 xhci_increment_ring(ring); 98 free_trbs--; 99 100 first_packet = false; 101 state->needs_transfer_trb = false; 102 if (transfer_size == 0) { 103 // ZLP (if there was one) has been sent 104 state->needs_zlp = false; 105 } 106 } 107 108 if (state->phys_iter.offset < header->length) { 109 // still more data to queue, but we are out of TRBs. 110 // come back and finish later. 111 return ZX_ERR_SHOULD_WAIT; 112 } 113 114 if (state->needs_data_event) { 115 if (free_trbs == 0) { 116 // will need to do this later 117 return ZX_ERR_SHOULD_WAIT; 118 } 119 120 // Queue event data TRB 121 xhci_trb_t* trb = ring->current; 122 xhci_clear_trb(trb); 123 trb_set_ptr(trb, req); 124 XHCI_SET_BITS32(&trb->status, XFER_TRB_INTR_TARGET_START, XFER_TRB_INTR_TARGET_BITS, 125 interrupter_target); 126 trb_set_control(trb, TRB_TRANSFER_EVENT_DATA, XFER_TRB_IOC); 127 if (driver_get_log_flags() & DDK_LOG_SPEW) xhci_print_trb(ring, trb); 128 xhci_increment_ring(ring); 129 free_trbs--; 130 state->needs_data_event = false; 131 } 132 return ZX_OK; 133} 134