xhci: refactor and cleanup endpoint initialization.
xhci_endpoint_init() and helper functions were a bit messy. Adding the higher bandwidth SuperSpeedPlus Isoc support on top of it would make it even harder to read. No functional changes. Signed-off-by: Mathias Nyman <mathias.nyman@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
faee822c5a
commit
def4e6f7b4
|
@ -1326,7 +1326,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
|
||||||
default:
|
default:
|
||||||
BUG();
|
BUG();
|
||||||
}
|
}
|
||||||
return EP_INTERVAL(interval);
|
return interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The "Mult" field in the endpoint context is only set for SuperSpeed isoc eps.
|
/* The "Mult" field in the endpoint context is only set for SuperSpeed isoc eps.
|
||||||
|
@ -1343,33 +1343,36 @@ static u32 xhci_get_endpoint_mult(struct usb_device *udev,
|
||||||
return ep->ss_ep_comp.bmAttributes;
|
return ep->ss_ep_comp.bmAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static u32 xhci_get_endpoint_max_burst(struct usb_device *udev,
|
||||||
|
struct usb_host_endpoint *ep)
|
||||||
|
{
|
||||||
|
/* Super speed and Plus have max burst in ep companion desc */
|
||||||
|
if (udev->speed >= USB_SPEED_SUPER)
|
||||||
|
return ep->ss_ep_comp.bMaxBurst;
|
||||||
|
|
||||||
|
if (udev->speed == USB_SPEED_HIGH &&
|
||||||
|
(usb_endpoint_xfer_isoc(&ep->desc) ||
|
||||||
|
usb_endpoint_xfer_int(&ep->desc)))
|
||||||
|
return (usb_endpoint_maxp(&ep->desc) & 0x1800) >> 11;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep)
|
static u32 xhci_get_endpoint_type(struct usb_host_endpoint *ep)
|
||||||
{
|
{
|
||||||
int in;
|
int in;
|
||||||
u32 type;
|
|
||||||
|
|
||||||
in = usb_endpoint_dir_in(&ep->desc);
|
in = usb_endpoint_dir_in(&ep->desc);
|
||||||
if (usb_endpoint_xfer_control(&ep->desc)) {
|
|
||||||
type = EP_TYPE(CTRL_EP);
|
if (usb_endpoint_xfer_control(&ep->desc))
|
||||||
} else if (usb_endpoint_xfer_bulk(&ep->desc)) {
|
return CTRL_EP;
|
||||||
if (in)
|
if (usb_endpoint_xfer_bulk(&ep->desc))
|
||||||
type = EP_TYPE(BULK_IN_EP);
|
return in ? BULK_IN_EP : BULK_OUT_EP;
|
||||||
else
|
if (usb_endpoint_xfer_isoc(&ep->desc))
|
||||||
type = EP_TYPE(BULK_OUT_EP);
|
return in ? ISOC_IN_EP : ISOC_OUT_EP;
|
||||||
} else if (usb_endpoint_xfer_isoc(&ep->desc)) {
|
if (usb_endpoint_xfer_int(&ep->desc))
|
||||||
if (in)
|
return in ? INT_IN_EP : INT_OUT_EP;
|
||||||
type = EP_TYPE(ISOC_IN_EP);
|
return 0;
|
||||||
else
|
|
||||||
type = EP_TYPE(ISOC_OUT_EP);
|
|
||||||
} else if (usb_endpoint_xfer_int(&ep->desc)) {
|
|
||||||
if (in)
|
|
||||||
type = EP_TYPE(INT_IN_EP);
|
|
||||||
else
|
|
||||||
type = EP_TYPE(INT_OUT_EP);
|
|
||||||
} else {
|
|
||||||
type = 0;
|
|
||||||
}
|
|
||||||
return type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the maximum endpoint service interval time (ESIT) payload.
|
/* Return the maximum endpoint service interval time (ESIT) payload.
|
||||||
|
@ -1409,10 +1412,14 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||||
struct xhci_ep_ctx *ep_ctx;
|
struct xhci_ep_ctx *ep_ctx;
|
||||||
struct xhci_ring *ep_ring;
|
struct xhci_ring *ep_ring;
|
||||||
unsigned int max_packet;
|
unsigned int max_packet;
|
||||||
unsigned int max_burst;
|
enum xhci_ring_type ring_type;
|
||||||
enum xhci_ring_type type;
|
|
||||||
u32 max_esit_payload;
|
u32 max_esit_payload;
|
||||||
u32 endpoint_type;
|
u32 endpoint_type;
|
||||||
|
unsigned int max_burst;
|
||||||
|
unsigned int interval;
|
||||||
|
unsigned int mult;
|
||||||
|
unsigned int avg_trb_len;
|
||||||
|
unsigned int err_count = 0;
|
||||||
|
|
||||||
ep_index = xhci_get_endpoint_index(&ep->desc);
|
ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||||
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
|
ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
|
||||||
|
@ -1420,12 +1427,11 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||||
endpoint_type = xhci_get_endpoint_type(ep);
|
endpoint_type = xhci_get_endpoint_type(ep);
|
||||||
if (!endpoint_type)
|
if (!endpoint_type)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
ep_ctx->ep_info2 = cpu_to_le32(endpoint_type);
|
|
||||||
|
|
||||||
type = usb_endpoint_type(&ep->desc);
|
ring_type = usb_endpoint_type(&ep->desc);
|
||||||
/* Set up the endpoint ring */
|
/* Set up the endpoint ring */
|
||||||
virt_dev->eps[ep_index].new_ring =
|
virt_dev->eps[ep_index].new_ring =
|
||||||
xhci_ring_alloc(xhci, 2, 1, type, mem_flags);
|
xhci_ring_alloc(xhci, 2, 1, ring_type, mem_flags);
|
||||||
if (!virt_dev->eps[ep_index].new_ring) {
|
if (!virt_dev->eps[ep_index].new_ring) {
|
||||||
/* Attempt to use the ring cache */
|
/* Attempt to use the ring cache */
|
||||||
if (virt_dev->num_rings_cached == 0)
|
if (virt_dev->num_rings_cached == 0)
|
||||||
|
@ -1435,81 +1441,48 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
|
||||||
virt_dev->ring_cache[virt_dev->num_rings_cached];
|
virt_dev->ring_cache[virt_dev->num_rings_cached];
|
||||||
virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
|
virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL;
|
||||||
xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring,
|
xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring,
|
||||||
1, type);
|
1, ring_type);
|
||||||
}
|
}
|
||||||
virt_dev->eps[ep_index].skip = false;
|
virt_dev->eps[ep_index].skip = false;
|
||||||
ep_ring = virt_dev->eps[ep_index].new_ring;
|
ep_ring = virt_dev->eps[ep_index].new_ring;
|
||||||
ep_ctx->deq = cpu_to_le64(ep_ring->first_seg->dma | ep_ring->cycle_state);
|
|
||||||
|
|
||||||
ep_ctx->ep_info = cpu_to_le32(xhci_get_endpoint_interval(udev, ep)
|
/*
|
||||||
| EP_MULT(xhci_get_endpoint_mult(udev, ep)));
|
* Get values to fill the endpoint context, mostly from ep descriptor.
|
||||||
|
* The average TRB buffer lengt for bulk endpoints is unclear as we
|
||||||
|
* have no clue on scatter gather list entry size. For Isoc and Int,
|
||||||
|
* set it to max available. See xHCI 1.1 spec 4.14.1.1 for details.
|
||||||
|
*/
|
||||||
|
max_esit_payload = xhci_get_max_esit_payload(udev, ep);
|
||||||
|
interval = xhci_get_endpoint_interval(udev, ep);
|
||||||
|
mult = xhci_get_endpoint_mult(udev, ep);
|
||||||
|
max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
|
||||||
|
max_burst = xhci_get_endpoint_max_burst(udev, ep);
|
||||||
|
avg_trb_len = max_esit_payload;
|
||||||
|
|
||||||
/* FIXME dig Mult and streams info out of ep companion desc */
|
/* FIXME dig Mult and streams info out of ep companion desc */
|
||||||
|
|
||||||
/* Allow 3 retries for everything but isoc;
|
/* Allow 3 retries for everything but isoc, set CErr = 3 */
|
||||||
* CErr shall be set to 0 for Isoch endpoints.
|
|
||||||
*/
|
|
||||||
if (!usb_endpoint_xfer_isoc(&ep->desc))
|
if (!usb_endpoint_xfer_isoc(&ep->desc))
|
||||||
ep_ctx->ep_info2 |= cpu_to_le32(ERROR_COUNT(3));
|
err_count = 3;
|
||||||
else
|
/* Some devices get this wrong */
|
||||||
ep_ctx->ep_info2 |= cpu_to_le32(ERROR_COUNT(0));
|
if (usb_endpoint_xfer_bulk(&ep->desc) && udev->speed == USB_SPEED_HIGH)
|
||||||
|
max_packet = 512;
|
||||||
/* Set the max packet size and max burst */
|
/* xHCI 1.0 and 1.1 indicates that ctrl ep avg TRB Length should be 8 */
|
||||||
max_packet = GET_MAX_PACKET(usb_endpoint_maxp(&ep->desc));
|
|
||||||
max_burst = 0;
|
|
||||||
switch (udev->speed) {
|
|
||||||
case USB_SPEED_SUPER_PLUS:
|
|
||||||
case USB_SPEED_SUPER:
|
|
||||||
/* dig out max burst from ep companion desc */
|
|
||||||
max_burst = ep->ss_ep_comp.bMaxBurst;
|
|
||||||
break;
|
|
||||||
case USB_SPEED_HIGH:
|
|
||||||
/* Some devices get this wrong */
|
|
||||||
if (usb_endpoint_xfer_bulk(&ep->desc))
|
|
||||||
max_packet = 512;
|
|
||||||
/* bits 11:12 specify the number of additional transaction
|
|
||||||
* opportunities per microframe (USB 2.0, section 9.6.6)
|
|
||||||
*/
|
|
||||||
if (usb_endpoint_xfer_isoc(&ep->desc) ||
|
|
||||||
usb_endpoint_xfer_int(&ep->desc)) {
|
|
||||||
max_burst = (usb_endpoint_maxp(&ep->desc)
|
|
||||||
& 0x1800) >> 11;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case USB_SPEED_FULL:
|
|
||||||
case USB_SPEED_LOW:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet) |
|
|
||||||
MAX_BURST(max_burst));
|
|
||||||
max_esit_payload = xhci_get_max_esit_payload(udev, ep);
|
|
||||||
ep_ctx->tx_info = cpu_to_le32(MAX_ESIT_PAYLOAD_FOR_EP(max_esit_payload));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX no idea how to calculate the average TRB buffer length for bulk
|
|
||||||
* endpoints, as the driver gives us no clue how big each scatter gather
|
|
||||||
* list entry (or buffer) is going to be.
|
|
||||||
*
|
|
||||||
* For isochronous and interrupt endpoints, we set it to the max
|
|
||||||
* available, until we have new API in the USB core to allow drivers to
|
|
||||||
* declare how much bandwidth they actually need.
|
|
||||||
*
|
|
||||||
* Normally, it would be calculated by taking the total of the buffer
|
|
||||||
* lengths in the TD and then dividing by the number of TRBs in a TD,
|
|
||||||
* including link TRBs, No-op TRBs, and Event data TRBs. Since we don't
|
|
||||||
* use Event Data TRBs, and we don't chain in a link TRB on short
|
|
||||||
* transfers, we're basically dividing by 1.
|
|
||||||
*
|
|
||||||
* xHCI 1.0 and 1.1 specification indicates that the Average TRB Length
|
|
||||||
* should be set to 8 for control endpoints.
|
|
||||||
*/
|
|
||||||
if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100)
|
if (usb_endpoint_xfer_control(&ep->desc) && xhci->hci_version >= 0x100)
|
||||||
ep_ctx->tx_info |= cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(8));
|
avg_trb_len = 8;
|
||||||
else
|
|
||||||
ep_ctx->tx_info |=
|
/* Fill the endpoint context */
|
||||||
cpu_to_le32(AVG_TRB_LENGTH_FOR_EP(max_esit_payload));
|
ep_ctx->ep_info = cpu_to_le32(EP_INTERVAL(interval) |
|
||||||
|
EP_MULT(mult));
|
||||||
|
ep_ctx->ep_info2 = cpu_to_le32(EP_TYPE(endpoint_type) |
|
||||||
|
MAX_PACKET(max_packet) |
|
||||||
|
MAX_BURST(max_burst) |
|
||||||
|
ERROR_COUNT(err_count));
|
||||||
|
ep_ctx->deq = cpu_to_le64(ep_ring->first_seg->dma |
|
||||||
|
ep_ring->cycle_state);
|
||||||
|
|
||||||
|
ep_ctx->tx_info = cpu_to_le32(EP_MAX_ESIT_PAYLOAD_LO(max_esit_payload) |
|
||||||
|
EP_AVG_TRB_LENGTH(avg_trb_len));
|
||||||
|
|
||||||
/* FIXME Debug endpoint context */
|
/* FIXME Debug endpoint context */
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -749,8 +749,8 @@ struct xhci_ep_ctx {
|
||||||
#define GET_MAX_PACKET(p) ((p) & 0x7ff)
|
#define GET_MAX_PACKET(p) ((p) & 0x7ff)
|
||||||
|
|
||||||
/* tx_info bitmasks */
|
/* tx_info bitmasks */
|
||||||
#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff)
|
#define EP_AVG_TRB_LENGTH(p) ((p) & 0xffff)
|
||||||
#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16)
|
#define EP_MAX_ESIT_PAYLOAD_LO(p) (((p) & 0xffff) << 16)
|
||||||
#define CTX_TO_MAX_ESIT_PAYLOAD(p) (((p) >> 16) & 0xffff)
|
#define CTX_TO_MAX_ESIT_PAYLOAD(p) (((p) >> 16) & 0xffff)
|
||||||
|
|
||||||
/* deq bitmasks */
|
/* deq bitmasks */
|
||||||
|
|
Loading…
Reference in New Issue