Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 264929
b: refs/heads/master
c: 9af5d71
h: refs/heads/master
i:
  264927: 84b48f0
v: v3
  • Loading branch information
Sarah Sharp authored and Greg Kroah-Hartman committed Sep 9, 2011
1 parent 6412812 commit 830c8a0
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 839c817ce67178ca3c7c7ad534c571bba1e69ebe
refs/heads/master: 9af5d71d8e1fc404ad2ac1b568dafa1a2f9b3be2
63 changes: 63 additions & 0 deletions trunk/drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1410,6 +1410,69 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
*/
}

void xhci_clear_endpoint_bw_info(struct xhci_bw_info *bw_info)
{
bw_info->ep_interval = 0;
bw_info->mult = 0;
bw_info->num_packets = 0;
bw_info->max_packet_size = 0;
bw_info->type = 0;
bw_info->max_esit_payload = 0;
}

void xhci_update_bw_info(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_input_control_ctx *ctrl_ctx,
struct xhci_virt_device *virt_dev)
{
struct xhci_bw_info *bw_info;
struct xhci_ep_ctx *ep_ctx;
unsigned int ep_type;
int i;

for (i = 1; i < 31; ++i) {
bw_info = &virt_dev->eps[i].bw_info;

/* We can't tell what endpoint type is being dropped, but
* unconditionally clearing the bandwidth info for non-periodic
* endpoints should be harmless because the info will never be
* set in the first place.
*/
if (!EP_IS_ADDED(ctrl_ctx, i) && EP_IS_DROPPED(ctrl_ctx, i)) {
/* Dropped endpoint */
xhci_clear_endpoint_bw_info(bw_info);
continue;
}

if (EP_IS_ADDED(ctrl_ctx, i)) {
ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, i);
ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2));

/* Ignore non-periodic endpoints */
if (ep_type != ISOC_OUT_EP && ep_type != INT_OUT_EP &&
ep_type != ISOC_IN_EP &&
ep_type != INT_IN_EP)
continue;

/* Added or changed endpoint */
bw_info->ep_interval = CTX_TO_EP_INTERVAL(
le32_to_cpu(ep_ctx->ep_info));
bw_info->mult = CTX_TO_EP_MULT(
le32_to_cpu(ep_ctx->ep_info));
/* Number of packets is zero-based in the input context,
* but we want one-based for the interval table.
*/
bw_info->num_packets = CTX_TO_MAX_BURST(
le32_to_cpu(ep_ctx->ep_info2)) + 1;
bw_info->max_packet_size = MAX_PACKET_DECODED(
le32_to_cpu(ep_ctx->ep_info2));
bw_info->type = ep_type;
bw_info->max_esit_payload = CTX_TO_MAX_ESIT_PAYLOAD(
le32_to_cpu(ep_ctx->tx_info));
}
}
}

/* Copy output xhci_ep_ctx to the input xhci_ep_ctx copy.
* Useful when you want to change one particular aspect of the endpoint and then
* issue a configure endpoint command.
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/usb/host/xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -1912,6 +1912,7 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
!(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1))))
xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
}
xhci_update_bw_info(xhci, virt_dev->in_ctx, ctrl_ctx, virt_dev);
xhci_zero_in_ctx(xhci, virt_dev);
/*
* Install any rings for completely new endpoints or changed endpoints,
Expand Down Expand Up @@ -2668,6 +2669,7 @@ int xhci_discover_or_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
xhci_free_or_cache_endpoint_ring(xhci, virt_dev, i);
last_freed_endpoint = i;
}
xhci_clear_endpoint_bw_info(&virt_dev->eps[i].bw_info);
}
xhci_dbg(xhci, "Output context after successful reset device cmd:\n");
xhci_dbg_ctx(xhci, virt_dev->out_ctx, last_freed_endpoint);
Expand Down
31 changes: 31 additions & 0 deletions trunk/drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -611,11 +611,13 @@ struct xhci_ep_ctx {
#define EP_STATE_ERROR 4
/* Mult - Max number of burtst within an interval, in EP companion desc. */
#define EP_MULT(p) (((p) & 0x3) << 8)
#define CTX_TO_EP_MULT(p) (((p) >> 8) & 0x3)
/* bits 10:14 are Max Primary Streams */
/* bit 15 is Linear Stream Array */
/* Interval - period between requests to an endpoint - 125u increments. */
#define EP_INTERVAL(p) (((p) & 0xff) << 16)
#define EP_INTERVAL_TO_UFRAMES(p) (1 << (((p) >> 16) & 0xff))
#define CTX_TO_EP_INTERVAL(p) (((p) >> 16) & 0xff)
#define EP_MAXPSTREAMS_MASK (0x1f << 10)
#define EP_MAXPSTREAMS(p) (((p) << 10) & EP_MAXPSTREAMS_MASK)
/* Endpoint is set up with a Linear Stream Array (vs. Secondary Stream Array) */
Expand All @@ -640,6 +642,7 @@ struct xhci_ep_ctx {
/* bit 6 reserved */
/* bit 7 is Host Initiate Disable - for disabling stream selection */
#define MAX_BURST(p) (((p)&0xff) << 8)
#define CTX_TO_MAX_BURST(p) (((p) >> 8) & 0xff)
#define MAX_PACKET(p) (((p)&0xffff) << 16)
#define MAX_PACKET_MASK (0xffff << 16)
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
Expand All @@ -652,6 +655,7 @@ struct xhci_ep_ctx {
/* tx_info bitmasks */
#define AVG_TRB_LENGTH_FOR_EP(p) ((p) & 0xffff)
#define MAX_ESIT_PAYLOAD_FOR_EP(p) (((p) & 0xffff) << 16)
#define CTX_TO_MAX_ESIT_PAYLOAD(p) (((p) >> 16) & 0xffff)

/* deq bitmasks */
#define EP_CTX_CYCLE_MASK (1 << 0)
Expand All @@ -670,6 +674,11 @@ struct xhci_input_control_ctx {
__le32 rsvd2[6];
};

#define EP_IS_ADDED(ctrl_ctx, i) \
(le32_to_cpu(ctrl_ctx->add_flags) & (1 << (i + 1)))
#define EP_IS_DROPPED(ctrl_ctx, i) \
(le32_to_cpu(ctrl_ctx->drop_flags) & (1 << (i + 1)))

/* Represents everything that is needed to issue a command on the command ring.
* It's useful to pre-allocate these for commands that cannot fail due to
* out-of-memory errors, like freeing streams.
Expand Down Expand Up @@ -731,6 +740,22 @@ struct xhci_stream_info {
#define SMALL_STREAM_ARRAY_SIZE 256
#define MEDIUM_STREAM_ARRAY_SIZE 1024

/* Some Intel xHCI host controllers need software to keep track of the bus
* bandwidth. Keep track of endpoint info here. Each root port is allocated
* the full bus bandwidth. We must also treat TTs (including each port under a
* multi-TT hub) as a separate bandwidth domain. The direct memory interface
* (DMI) also limits the total bandwidth (across all domains) that can be used.
*/
struct xhci_bw_info {
unsigned int ep_interval;
/* mult and num_packets are zero-based */
unsigned int mult;
unsigned int num_packets;
unsigned int max_packet_size;
unsigned int max_esit_payload;
unsigned int type;
};

struct xhci_virt_ep {
struct xhci_ring *ring;
/* Related to endpoints that are configured to use stream IDs only */
Expand Down Expand Up @@ -772,6 +797,7 @@ struct xhci_virt_ep {
* process the missed tds on the endpoint ring.
*/
bool skip;
struct xhci_bw_info bw_info;
};

enum xhci_overhead_type {
Expand Down Expand Up @@ -1485,6 +1511,11 @@ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc);
unsigned int xhci_get_endpoint_flag_from_index(unsigned int ep_index);
unsigned int xhci_last_valid_endpoint(u32 added_ctxs);
void xhci_endpoint_zero(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_host_endpoint *ep);
void xhci_clear_endpoint_bw_info(struct xhci_bw_info *bw_info);
void xhci_update_bw_info(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_input_control_ctx *ctrl_ctx,
struct xhci_virt_device *virt_dev);
void xhci_endpoint_copy(struct xhci_hcd *xhci,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx,
Expand Down

0 comments on commit 830c8a0

Please sign in to comment.