Changeset 47e9494 in mainline for uspace/drv/bus/usb/xhci/endpoint.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/endpoint.c
r7d1dd2b r47e9494 44 44 #include "commands.h" 45 45 #include "endpoint.h" 46 #include "streams.h" 46 47 47 48 static int alloc_transfer_ds(xhci_endpoint_t *); … … 131 132 * @return EP_TYPE_[CONTROL|ISOCH|BULK|INTERRUPT]_[IN|OUT] 132 133 */ 133 staticint xhci_endpoint_type(xhci_endpoint_t *ep)134 int xhci_endpoint_type(xhci_endpoint_t *ep) 134 135 { 135 136 const bool in = ep->base.direction == USB_DIRECTION_IN; … … 153 154 154 155 return EP_TYPE_INVALID; 155 }156 157 /**158 * Test whether an XHCI endpoint uses streams.159 * @param[in] xhci_ep XHCI endpoint to query.160 *161 * @return True if the endpoint uses streams.162 */163 static bool endpoint_using_streams(xhci_endpoint_t *xhci_ep)164 {165 return xhci_ep->primary_stream_ctx_array != NULL;166 }167 168 // static bool primary_stream_ctx_has_secondary_array(xhci_stream_ctx_t *primary_ctx) {169 // /* Section 6.2.4.1, SCT values */170 // return XHCI_STREAM_SCT(*primary_ctx) >= 2;171 // }172 //173 // static size_t secondary_stream_ctx_array_size(xhci_stream_ctx_t *primary_ctx) {174 // if (XHCI_STREAM_SCT(*primary_ctx) < 2) return 0;175 // return 2 << XHCI_STREAM_SCT(*primary_ctx);176 // }177 178 /** Initialize primary streams of XHCI bulk endpoint.179 * @param[in] hc Host controller of the endpoint.180 * @param[in] xhci_epi XHCI bulk endpoint to use.181 * @param[in] count Number of primary streams to initialize.182 */183 static void initialize_primary_streams(xhci_hc_t *hc, xhci_endpoint_t *xhci_ep, unsigned count) {184 for (size_t index = 0; index < count; ++index) {185 xhci_stream_ctx_t *ctx = &xhci_ep->primary_stream_ctx_array[index];186 xhci_trb_ring_t *ring = &xhci_ep->primary_stream_rings[index];187 188 /* Init and register TRB ring for every primary stream */189 xhci_trb_ring_init(ring); // FIXME: Not checking error code?190 XHCI_STREAM_DEQ_PTR_SET(*ctx, ring->dequeue);191 192 /* Set to linear stream array */193 XHCI_STREAM_SCT_SET(*ctx, 1);194 }195 }196 197 /** Configure XHCI bulk endpoint's stream context.198 * @param[in] xhci_ep Associated XHCI bulk endpoint.199 * @param[in] ctx Endpoint context to configure.200 * @param[in] pstreams The value of MaxPStreams.201 */202 static void setup_stream_context(xhci_endpoint_t *xhci_ep, xhci_ep_ctx_t *ctx, unsigned pstreams) {203 XHCI_EP_TYPE_SET(*ctx, xhci_endpoint_type(xhci_ep));204 XHCI_EP_MAX_PACKET_SIZE_SET(*ctx, xhci_ep->base.max_packet_size);205 XHCI_EP_MAX_BURST_SIZE_SET(*ctx, xhci_ep->max_burst - 1);206 XHCI_EP_ERROR_COUNT_SET(*ctx, 3);207 208 XHCI_EP_MAX_P_STREAMS_SET(*ctx, pstreams);209 XHCI_EP_TR_DPTR_SET(*ctx, xhci_ep->primary_stream_ctx_dma.phys);210 // TODO: set HID?211 XHCI_EP_LSA_SET(*ctx, 1);212 }213 214 /** TODO document this215 */216 int xhci_endpoint_request_streams(xhci_hc_t *hc, xhci_device_t *dev, xhci_endpoint_t *xhci_ep, unsigned count) {217 if (xhci_ep->base.transfer_type != USB_TRANSFER_BULK218 || dev->base.speed != USB_SPEED_SUPER) {219 usb_log_error("Streams are only supported by superspeed bulk endpoints.");220 return EINVAL;221 }222 223 if (xhci_ep->max_streams == 1) {224 usb_log_error("Streams are not supported by endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep));225 return EINVAL;226 }227 228 uint8_t max_psa_size = 2 << XHCI_REG_RD(hc->cap_regs, XHCI_CAP_MAX_PSA_SIZE);229 if (count > max_psa_size) {230 // FIXME: We don't support secondary stream arrays yet, so we just give up for this231 return ENOTSUP;232 }233 234 if (count > xhci_ep->max_streams) {235 usb_log_error("Endpoint " XHCI_EP_FMT " supports only %" PRIu32 " streams.",236 XHCI_EP_ARGS(*xhci_ep), xhci_ep->max_streams);237 return EINVAL;238 }239 240 if (count <= 1024) {241 usb_log_debug2("Allocating primary stream context array of size %u for endpoint " XHCI_EP_FMT,242 count, XHCI_EP_ARGS(*xhci_ep));243 if ((dma_buffer_alloc(&xhci_ep->primary_stream_ctx_dma, count * sizeof(xhci_stream_ctx_t))))244 return ENOMEM;245 xhci_ep->primary_stream_ctx_array = xhci_ep->primary_stream_ctx_dma.virt;246 247 xhci_ep->primary_stream_rings = calloc(count, sizeof(xhci_trb_ring_t));248 if (!xhci_ep->primary_stream_rings) {249 dma_buffer_free(&xhci_ep->primary_stream_ctx_dma);250 return ENOMEM;251 }252 253 // FIXME: count should be rounded to nearest power of 2 for xHC, workaround for now254 count = 1024;255 // FIXME: pstreams are "log2(count) - 1"256 const size_t pstreams = 9;257 xhci_ep->primary_stream_ctx_array_size = count;258 259 memset(xhci_ep->primary_stream_ctx_array, 0, count * sizeof(xhci_stream_ctx_t));260 initialize_primary_streams(hc, xhci_ep, count);261 262 xhci_ep_ctx_t ep_ctx;263 setup_stream_context(xhci_ep, &ep_ctx, pstreams);264 return hc_add_endpoint(hc, dev->slot_id, xhci_endpoint_index(xhci_ep), &ep_ctx);265 }266 // FIXME: Complex stuff not supported yet267 return ENOTSUP;268 156 } 269 157 … … 300 188 static void free_transfer_ds(xhci_endpoint_t *xhci_ep) 301 189 { 302 if (endpoint_using_streams(xhci_ep)) { 303 usb_log_debug2("Freeing primary stream context array of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep)); 304 305 // maybe check if LSA, then skip? 306 // for (size_t index = 0; index < primary_stream_ctx_array_size(xhci_ep); ++index) { 307 // xhci_stream_ctx_t *primary_ctx = xhci_ep->primary_stream_ctx_array + index; 308 // if (primary_stream_ctx_has_secondary_array(primary_ctx)) { 309 // // uintptr_t phys = XHCI_STREAM_DEQ_PTR(*primary_ctx); 310 // /* size_t size = */ secondary_stream_ctx_array_size(primary_ctx); 311 // // TODO: somehow map the address to virtual and free the secondary array 312 // } 313 // } 314 for (size_t index = 0; index < xhci_ep->primary_stream_ctx_array_size; ++index) { 315 // FIXME: Get the trb ring associated with stream [index] and fini it 316 } 317 dma_buffer_free(&xhci_ep->primary_stream_ctx_dma); 190 if (xhci_ep->primary_stream_data_size) { 191 xhci_stream_free_ds(xhci_ep); 318 192 } else { 319 193 usb_log_debug2("Freeing main transfer ring of endpoint " XHCI_EP_FMT, XHCI_EP_ARGS(*xhci_ep)); 320 321 194 xhci_trb_ring_fini(&xhci_ep->ring); 322 195 }
Note:
See TracChangeset
for help on using the changeset viewer.