Print this page
MFV: illumos-gate@2aba3acda67326648fd60aaf2bfb4e18ee8c04ed
9816 Multi-TRB xhci transfers should use event data
9817 xhci needs to always set slot context
8550 increase xhci bulk transfer sgl count
9818 xhci_transfer_get_tdsize can return values that are too large
Reviewed by: Alex Wilson <alex.wilson@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Joshua M. Clulow <josh@sysmgr.org>
Author: Robert Mustacchi <rm@joyent.com>

*** 8,18 **** * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright 2016 Joyent, Inc. */ #ifndef _SYS_USB_XHCI_XHCI_H #define _SYS_USB_XHCI_XHCI_H --- 8,18 ---- * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* ! * Copyright (c) 2018, Joyent, Inc. */ #ifndef _SYS_USB_XHCI_XHCI_H #define _SYS_USB_XHCI_XHCI_H
*** 54,75 **** * driver. However, for bulk transfers, which are the largest by far, we want to * be able to leverage SGLs to give us more DMA flexibility. * * We can transfer up to 64K in one transfer request block (TRB) which * corresponds to a single SGL entry. Each ring we create is a single page in ! * size and will support at most 256 TRBs. We've selected to use up to 8 SGLs ! * for these transfer cases. This allows us to put up to 512 KiB in a given ! * transfer request and in the worst case, we can have about 30 of them ! * outstanding. Experimentally, this has proven to be sufficient for most of the ! * drivers that we support today. */ ! #define XHCI_TRB_MAX_TRANSFER 65536 #define XHCI_DMA_ALIGN 64 #define XHCI_DEF_DMA_SGL 1 ! #define XHCI_TRANSFER_DMA_SGL 8 ! #define XHCI_MAX_TRANSFER (XHCI_TRB_MAX_TRANSFER * XHCI_TRANSFER_DMA_SGL) ! #define XHCI_DMA_STRUCT_SIZE 4096 /* * Properties and values for rerouting ehci ports to xhci. */ #define XHCI_PROP_REROUTE_DISABLE 0 --- 54,93 ---- * driver. However, for bulk transfers, which are the largest by far, we want to * be able to leverage SGLs to give us more DMA flexibility. * * We can transfer up to 64K in one transfer request block (TRB) which * corresponds to a single SGL entry. Each ring we create is a single page in ! * size and will support at most 256 TRBs. To try and give the operating system ! * flexibility when allocating DMA transfers, we've opted to allow up to 63 ! * SGLs. Because there isn't a good way to support DMA windows with the xHCI ! * controller design, if this number is too small then DMA allocations and ! * binding might fail. If the DMA binding fails, the transfer will fail. ! * ! * The reason that we use 63 SGLs and not the expected 64 is that we always need ! * to allocate an additional TRB for the event data. This leaves us with a ! * nicely divisible number of entries. ! * ! * The final piece of this is the maximum sized transfer that the driver ! * advertises to the broader framework. This is currently sized at 512 KiB. For ! * reference the ehci driver sized this value at 640 KiB. It's important to ! * understand that this isn't reflected in the DMA attribute limitation, because ! * it's not an attribute of the hardware. Experimentally, this has proven to be ! * sufficient for most of the drivers that we support today. When considering ! * increasing this number, please note the impact that might have on the ! * required number of DMA SGL entries required to satisfy the allocation. ! * ! * The value of 512 KiB was originally based on the number of SGLs we supported ! * multiplied by the maximum transfer size. The original number of ! * XHCI_TRANSFER_DMA_SGL was 8. The 512 KiB value was based upon taking the ! * number of SGLs and assuming that each TRB used its maximum transfer size of ! * 64 KiB. */ ! #define XHCI_TRB_MAX_TRANSFER 65536 /* 64 KiB */ #define XHCI_DMA_ALIGN 64 #define XHCI_DEF_DMA_SGL 1 ! #define XHCI_TRANSFER_DMA_SGL 63 ! #define XHCI_MAX_TRANSFER 524288 /* 512 KiB */ /* * Properties and values for rerouting ehci ports to xhci. */ #define XHCI_PROP_REROUTE_DISABLE 0
*** 96,105 **** --- 114,130 ---- (dma).xdb_dma_handle, 0, 0, \ (flag))) #endif /* + * TRBs need to indicate the number of remaining USB packets in the overall + * transfer. This is a 5-bit value, which means that the maximum value we can + * store in that TRD field is 31. + */ + #define XHCI_MAX_TDSIZE 31 + + /* * This defines a time in 2-ms ticks that is required to wait for the controller * to be ready to go. Section 5.4.8 of the XHCI specification in the description * of the PORTSC register indicates that the upper bound is 20 ms. Therefore the * number of ticks is 10. */
*** 308,317 **** --- 333,343 ---- uint_t xt_short; uint_t xt_timeout; usb_cr_t xt_cr; boolean_t xt_data_tohost; xhci_trb_t *xt_trbs; + uint64_t *xt_trbs_pa; usb_isoc_pkt_descr_t *xt_isoc; usb_opaque_t xt_usba_req; } xhci_transfer_t; /*
*** 646,656 **** /* * DMA Transfer Ring functions */ extern xhci_transfer_t *xhci_transfer_alloc(xhci_t *, xhci_endpoint_t *, size_t, ! int, int); extern void xhci_transfer_free(xhci_t *, xhci_transfer_t *); extern void xhci_transfer_copy(xhci_transfer_t *, void *, size_t, boolean_t); extern int xhci_transfer_sync(xhci_t *, xhci_transfer_t *, uint_t); extern void xhci_transfer_trb_fill_data(xhci_endpoint_t *, xhci_transfer_t *, int, boolean_t); --- 672,682 ---- /* * DMA Transfer Ring functions */ extern xhci_transfer_t *xhci_transfer_alloc(xhci_t *, xhci_endpoint_t *, size_t, ! uint_t, int); extern void xhci_transfer_free(xhci_t *, xhci_transfer_t *); extern void xhci_transfer_copy(xhci_transfer_t *, void *, size_t, boolean_t); extern int xhci_transfer_sync(xhci_t *, xhci_transfer_t *, uint_t); extern void xhci_transfer_trb_fill_data(xhci_endpoint_t *, xhci_transfer_t *, int, boolean_t);
*** 712,722 **** */ extern boolean_t xhci_ring_trb_tail_valid(xhci_ring_t *, uint64_t); extern int xhci_ring_trb_valid_range(xhci_ring_t *, uint64_t, uint_t); extern boolean_t xhci_ring_trb_space(xhci_ring_t *, uint_t); ! extern void xhci_ring_trb_fill(xhci_ring_t *, uint_t, xhci_trb_t *, boolean_t); extern void xhci_ring_trb_produce(xhci_ring_t *, uint_t); extern boolean_t xhci_ring_trb_consumed(xhci_ring_t *, uint64_t); extern void xhci_ring_trb_put(xhci_ring_t *, xhci_trb_t *); extern void xhci_ring_skip(xhci_ring_t *); extern void xhci_ring_skip_transfer(xhci_ring_t *, xhci_transfer_t *); --- 738,749 ---- */ extern boolean_t xhci_ring_trb_tail_valid(xhci_ring_t *, uint64_t); extern int xhci_ring_trb_valid_range(xhci_ring_t *, uint64_t, uint_t); extern boolean_t xhci_ring_trb_space(xhci_ring_t *, uint_t); ! extern void xhci_ring_trb_fill(xhci_ring_t *, uint_t, xhci_trb_t *, uint64_t *, ! boolean_t); extern void xhci_ring_trb_produce(xhci_ring_t *, uint_t); extern boolean_t xhci_ring_trb_consumed(xhci_ring_t *, uint64_t); extern void xhci_ring_trb_put(xhci_ring_t *, xhci_trb_t *); extern void xhci_ring_skip(xhci_ring_t *); extern void xhci_ring_skip_transfer(xhci_ring_t *, xhci_transfer_t *);