Re: [PATCH/RFC v2] xhci: Support for 64-byte contexts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi John,

The patch looks good, except you forgot one PAGESIZE.  I've cleaned that
up and added both the patches to my master-dev branch.  I'll test on
Monday and send out the full xHCI bug fix patchset then.

Sarah Sharp

On Thu, Jul 16, 2009 at 07:06:15PM -0700, John Youn wrote:
> Adds support for controllers that use 64-byte contexts.  The following context
> data structures are affected by this: Device, Input, Input Control, Endpoint,
> and Slot.  To accommodate the use of either 32 or 64-byte contexts, a Device or
> Input context can only be accessed through functions which look-up and return
> pointers to their contained contexts.
> 
> Signed-off-by: John Youn <johnyoun@xxxxxxxxxxxx>
> ---
> 
> Fixed issues
> - code formatting, stray/obsolete comments, unnecessary function prototypes
> - print out reserved fields of 64-byte contexts
> - changed context allocation to 2112
> 
> 
>  drivers/usb/host/xhci-dbg.c  |  129 ++++++++++++++++++++++++++----------------
>  drivers/usb/host/xhci-hcd.c  |  119 ++++++++++++++++++++++----------------
>  drivers/usb/host/xhci-mem.c  |  121 ++++++++++++++++++++++++++++-----------
>  drivers/usb/host/xhci-ring.c |   22 +++++--
>  drivers/usb/host/xhci.h      |   62 +++++++++++---------
>  5 files changed, 285 insertions(+), 168 deletions(-)
> 
> diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
> index ab21341..705e343 100644
> --- a/drivers/usb/host/xhci-dbg.c
> +++ b/drivers/usb/host/xhci-dbg.c
> @@ -393,105 +393,138 @@ void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci)
>  			upper_32_bits(val));
>  }
>  
> -dma_addr_t xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_slot_ctx *slot, dma_addr_t dma)
> +/* Print the last 32 bytes for 64-byte contexts */
> +static void dbg_rsvd64(struct xhci_hcd *xhci, u64 *ctx, dma_addr_t dma)
> +{
> +	int i;
> +	for (i = 0; i < 4; ++i) {
> +		xhci_dbg(xhci, "@%p (virt) @%08llx "
> +			 "(dma) %#08llx - rsvd64[%d]\n",
> +			 &ctx[4 + i], (unsigned long long)dma,
> +			 ctx[4 + i], i);
> +		dma += 8;
> +	}
> +}
> +
> +void xhci_dbg_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx)
>  {
>  	/* Fields are 32 bits wide, DMA addresses are in bytes */
>  	int field_size = 32 / 8;
>  	int i;
>  
> +	struct xhci_slot_ctx *slot_ctx = xhci_get_slot_ctx(xhci, ctx);
> +	dma_addr_t dma = ctx->dma + ((unsigned long)slot_ctx - (unsigned long)ctx);
> +	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
> +
>  	xhci_dbg(xhci, "Slot Context:\n");
>  	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info\n",
> -			&slot->dev_info,
> -			(unsigned long long)dma, slot->dev_info);
> +			&slot_ctx->dev_info,
> +			(unsigned long long)dma, slot_ctx->dev_info);
>  	dma += field_size;
>  	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_info2\n",
> -			&slot->dev_info2,
> -			(unsigned long long)dma, slot->dev_info2);
> +			&slot_ctx->dev_info2,
> +			(unsigned long long)dma, slot_ctx->dev_info2);
>  	dma += field_size;
>  	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tt_info\n",
> -			&slot->tt_info,
> -			(unsigned long long)dma, slot->tt_info);
> +			&slot_ctx->tt_info,
> +			(unsigned long long)dma, slot_ctx->tt_info);
>  	dma += field_size;
>  	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - dev_state\n",
> -			&slot->dev_state,
> -			(unsigned long long)dma, slot->dev_state);
> +			&slot_ctx->dev_state,
> +			(unsigned long long)dma, slot_ctx->dev_state);
>  	dma += field_size;
> -	for (i = 0; i > 4; ++i) {
> +	for (i = 0; i < 4; ++i) {
>  		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
> -				&slot->reserved[i], (unsigned long long)dma,
> -				slot->reserved[i], i);
> +				&slot_ctx->reserved[i], (unsigned long long)dma,
> +				slot_ctx->reserved[i], i);
>  		dma += field_size;
>  	}
>  
> -	return dma;
> +	if (csz)
> +		dbg_rsvd64(xhci, (u64 *)slot_ctx, dma);
>  }
>  
> -dma_addr_t xhci_dbg_ep_ctx(struct xhci_hcd *xhci, struct xhci_ep_ctx *ep, dma_addr_t dma, unsigned int last_ep)
> +void xhci_dbg_ep_ctx(struct xhci_hcd *xhci,
> +		     struct xhci_container_ctx *ctx,
> +		     unsigned int last_ep)
>  {
>  	int i, j;
>  	int last_ep_ctx = 31;
>  	/* Fields are 32 bits wide, DMA addresses are in bytes */
>  	int field_size = 32 / 8;
> +	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
>  
>  	if (last_ep < 31)
>  		last_ep_ctx = last_ep + 1;
>  	for (i = 0; i < last_ep_ctx; ++i) {
> +		struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, ctx, i);
> +		dma_addr_t dma = ctx->dma +
> +			((unsigned long)ep_ctx - (unsigned long)ctx);
> +
>  		xhci_dbg(xhci, "Endpoint %02d Context:\n", i);
>  		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info\n",
> -				&ep[i].ep_info,
> -				(unsigned long long)dma, ep[i].ep_info);
> +				&ep_ctx->ep_info,
> +				(unsigned long long)dma, ep_ctx->ep_info);
>  		dma += field_size;
>  		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - ep_info2\n",
> -				&ep[i].ep_info2,
> -				(unsigned long long)dma, ep[i].ep_info2);
> +				&ep_ctx->ep_info2,
> +				(unsigned long long)dma, ep_ctx->ep_info2);
>  		dma += field_size;
>  		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08llx - deq\n",
> -				&ep[i].deq,
> -				(unsigned long long)dma, ep[i].deq);
> +				&ep_ctx->deq,
> +				(unsigned long long)dma, ep_ctx->deq);
>  		dma += 2*field_size;
>  		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - tx_info\n",
> -				&ep[i].tx_info,
> -				(unsigned long long)dma, ep[i].tx_info);
> +				&ep_ctx->tx_info,
> +				(unsigned long long)dma, ep_ctx->tx_info);
>  		dma += field_size;
>  		for (j = 0; j < 3; ++j) {
>  			xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd[%d]\n",
> -					&ep[i].reserved[j],
> +					&ep_ctx->reserved[j],
>  					(unsigned long long)dma,
> -					ep[i].reserved[j], j);
> +					ep_ctx->reserved[j], j);
>  			dma += field_size;
>  		}
> +
> +		if (csz)
> +			dbg_rsvd64(xhci, (u64 *)ep_ctx, dma);
>  	}
> -	return dma;
>  }
>  
> -void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep)
> +void xhci_dbg_ctx(struct xhci_hcd *xhci,
> +		  struct xhci_container_ctx *ctx,
> +		  unsigned int last_ep)
>  {
>  	int i;
>  	/* Fields are 32 bits wide, DMA addresses are in bytes */
>  	int field_size = 32 / 8;
> -
> -	/* Skip the 32 bytes of padding at the beginning */
> -	dma += 32;
> -	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
> -			&ctx->drop_flags, (unsigned long long)dma,
> -			ctx->drop_flags);
> -	dma += field_size;
> -	xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
> -			&ctx->add_flags, (unsigned long long)dma,
> -			ctx->add_flags);
> -	dma += field_size;
> -	for (i = 0; i < 6; ++i) {
> -		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
> -				&ctx->rsvd2[i], (unsigned long long)dma,
> -				ctx->rsvd2[i], i);
> +	struct xhci_slot_ctx *slot_ctx;
> +	dma_addr_t dma = ctx->dma;
> +	int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
> +
> +	if (ctx->type == XHCI_CTX_TYPE_INPUT) {
> +		struct xhci_input_control_ctx *ctrl_ctx =
> +			xhci_get_input_control_ctx(xhci, ctx);
> +		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - drop flags\n",
> +			 &ctrl_ctx->drop_flags, (unsigned long long)dma,
> +			 ctrl_ctx->drop_flags);
>  		dma += field_size;
> +		xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - add flags\n",
> +			 &ctrl_ctx->add_flags, (unsigned long long)dma,
> +			 ctrl_ctx->add_flags);
> +		dma += field_size;
> +		for (i = 0; i < 6; ++i) {
> +			xhci_dbg(xhci, "@%p (virt) @%08llx (dma) %#08x - rsvd2[%d]\n",
> +				 &ctrl_ctx->rsvd2[i], (unsigned long long)dma,
> +				 ctrl_ctx->rsvd2[i], i);
> +			dma += field_size;
> +		}
> +
> +		if (csz)
> +			dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma);
>  	}
> -	dma = xhci_dbg_slot_ctx(xhci, &ctx->slot, dma);
> -	dma = xhci_dbg_ep_ctx(xhci, ctx->ep, dma, last_ep);
> -}
>  
> -void xhci_dbg_device_ctx(struct xhci_hcd *xhci, struct xhci_device_ctx *ctx, dma_addr_t dma, unsigned int last_ep)
> -{
> -	dma = xhci_dbg_slot_ctx(xhci, &ctx->slot, dma);
> -	dma = xhci_dbg_ep_ctx(xhci, ctx->ep, dma, last_ep);
> +	slot_ctx = xhci_get_slot_ctx(xhci, ctx);
> +	xhci_dbg_slot_ctx(xhci, ctx);
> +	xhci_dbg_ep_ctx(xhci, ctx, last_ep);
>  }
> diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
> index 43f403c..c747010 100644
> --- a/drivers/usb/host/xhci-hcd.c
> +++ b/drivers/usb/host/xhci-hcd.c
> @@ -719,7 +719,9 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>  		struct usb_host_endpoint *ep)
>  {
>  	struct xhci_hcd *xhci;
> -	struct xhci_device_control *in_ctx;
> +	struct xhci_container_ctx *in_ctx, *out_ctx;
> +	struct xhci_input_control_ctx *ctrl_ctx;
> +	struct xhci_slot_ctx *slot_ctx;
>  	unsigned int last_ctx;
>  	unsigned int ep_index;
>  	struct xhci_ep_ctx *ep_ctx;
> @@ -747,31 +749,34 @@ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>  	}
>  
>  	in_ctx = xhci->devs[udev->slot_id]->in_ctx;
> +	out_ctx = xhci->devs[udev->slot_id]->out_ctx;
> +	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
>  	ep_index = xhci_get_endpoint_index(&ep->desc);
> -	ep_ctx = &xhci->devs[udev->slot_id]->out_ctx->ep[ep_index];
> +	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
>  	/* If the HC already knows the endpoint is disabled,
>  	 * or the HCD has noted it is disabled, ignore this request
>  	 */
>  	if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED ||
> -			in_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
> +			ctrl_ctx->drop_flags & xhci_get_endpoint_flag(&ep->desc)) {
>  		xhci_warn(xhci, "xHCI %s called with disabled ep %p\n",
>  				__func__, ep);
>  		return 0;
>  	}
>  
> -	in_ctx->drop_flags |= drop_flag;
> -	new_drop_flags = in_ctx->drop_flags;
> +	ctrl_ctx->drop_flags |= drop_flag;
> +	new_drop_flags = ctrl_ctx->drop_flags;
>  
> -	in_ctx->add_flags = ~drop_flag;
> -	new_add_flags = in_ctx->add_flags;
> +	ctrl_ctx->add_flags = ~drop_flag;
> +	new_add_flags = ctrl_ctx->add_flags;
>  
> -	last_ctx = xhci_last_valid_endpoint(in_ctx->add_flags);
> +	last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags);
> +	slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
>  	/* Update the last valid endpoint context, if we deleted the last one */
> -	if ((in_ctx->slot.dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
> -		in_ctx->slot.dev_info &= ~LAST_CTX_MASK;
> -		in_ctx->slot.dev_info |= LAST_CTX(last_ctx);
> +	if ((slot_ctx->dev_info & LAST_CTX_MASK) > LAST_CTX(last_ctx)) {
> +		slot_ctx->dev_info &= ~LAST_CTX_MASK;
> +		slot_ctx->dev_info |= LAST_CTX(last_ctx);
>  	}
> -	new_slot_info = in_ctx->slot.dev_info;
> +	new_slot_info = slot_ctx->dev_info;
>  
>  	xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep);
>  
> @@ -801,9 +806,11 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>  		struct usb_host_endpoint *ep)
>  {
>  	struct xhci_hcd *xhci;
> -	struct xhci_device_control *in_ctx;
> +	struct xhci_container_ctx *in_ctx, *out_ctx;
>  	unsigned int ep_index;
>  	struct xhci_ep_ctx *ep_ctx;
> +	struct xhci_slot_ctx *slot_ctx;
> +	struct xhci_input_control_ctx *ctrl_ctx;
>  	u32 added_ctxs;
>  	unsigned int last_ctx;
>  	u32 new_add_flags, new_drop_flags, new_slot_info;
> @@ -836,12 +843,14 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>  	}
>  
>  	in_ctx = xhci->devs[udev->slot_id]->in_ctx;
> +	out_ctx = xhci->devs[udev->slot_id]->out_ctx;
> +	ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
>  	ep_index = xhci_get_endpoint_index(&ep->desc);
> -	ep_ctx = &xhci->devs[udev->slot_id]->out_ctx->ep[ep_index];
> +	ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
>  	/* If the HCD has already noted the endpoint is enabled,
>  	 * ignore this request.
>  	 */
> -	if (in_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
> +	if (ctrl_ctx->add_flags & xhci_get_endpoint_flag(&ep->desc)) {
>  		xhci_warn(xhci, "xHCI %s called with enabled ep %p\n",
>  				__func__, ep);
>  		return 0;
> @@ -859,8 +868,8 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>  		return -ENOMEM;
>  	}
>  
> -	in_ctx->add_flags |= added_ctxs;
> -	new_add_flags = in_ctx->add_flags;
> +	ctrl_ctx->add_flags |= added_ctxs;
> +	new_add_flags = ctrl_ctx->add_flags;
>  
>  	/* If xhci_endpoint_disable() was called for this endpoint, but the
>  	 * xHC hasn't been notified yet through the check_bandwidth() call,
> @@ -868,14 +877,15 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>  	 * descriptors.  We must drop and re-add this endpoint, so we leave the
>  	 * drop flags alone.
>  	 */
> -	new_drop_flags = in_ctx->drop_flags;
> +	new_drop_flags = ctrl_ctx->drop_flags;
>  
> +	slot_ctx = xhci_get_slot_ctx(xhci, in_ctx);
>  	/* Update the last valid endpoint context, if we just added one past */
> -	if ((in_ctx->slot.dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
> -		in_ctx->slot.dev_info &= ~LAST_CTX_MASK;
> -		in_ctx->slot.dev_info |= LAST_CTX(last_ctx);
> +	if ((slot_ctx->dev_info & LAST_CTX_MASK) < LAST_CTX(last_ctx)) {
> +		slot_ctx->dev_info &= ~LAST_CTX_MASK;
> +		slot_ctx->dev_info |= LAST_CTX(last_ctx);
>  	}
> -	new_slot_info = in_ctx->slot.dev_info;
> +	new_slot_info = slot_ctx->dev_info;
>  
>  	/* Store the usb_device pointer for later use */
>  	ep->hcpriv = udev;
> @@ -889,9 +899,11 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
>  	return 0;
>  }
>  
> -static void xhci_zero_in_ctx(struct xhci_virt_device *virt_dev)
> +static void xhci_zero_in_ctx(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev)
>  {
> +	struct xhci_input_control_ctx *ctrl_ctx;
>  	struct xhci_ep_ctx *ep_ctx;
> +	struct xhci_slot_ctx *slot_ctx;
>  	int i;
>  
>  	/* When a device's add flag and drop flag are zero, any subsequent
> @@ -899,13 +911,15 @@ static void xhci_zero_in_ctx(struct xhci_virt_device *virt_dev)
>  	 * untouched.  Make sure we don't leave any old state in the input
>  	 * endpoint contexts.
>  	 */
> -	virt_dev->in_ctx->drop_flags = 0;
> -	virt_dev->in_ctx->add_flags = 0;
> -	virt_dev->in_ctx->slot.dev_info &= ~LAST_CTX_MASK;
> +	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
> +	ctrl_ctx->drop_flags = 0;
> +	ctrl_ctx->add_flags = 0;
> +	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
> +	slot_ctx->dev_info &= ~LAST_CTX_MASK;
>  	/* Endpoint 0 is always valid */
> -	virt_dev->in_ctx->slot.dev_info |= LAST_CTX(1);
> +	slot_ctx->dev_info |= LAST_CTX(1);
>  	for (i = 1; i < 31; ++i) {
> -		ep_ctx = &virt_dev->in_ctx->ep[i];
> +		ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, i);
>  		ep_ctx->ep_info = 0;
>  		ep_ctx->ep_info2 = 0;
>  		ep_ctx->deq = 0;
> @@ -931,6 +945,8 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
>  	unsigned long flags;
>  	struct xhci_hcd *xhci;
>  	struct xhci_virt_device	*virt_dev;
> +	struct xhci_input_control_ctx *ctrl_ctx;
> +	struct xhci_slot_ctx *slot_ctx;
>  
>  	ret = xhci_check_args(hcd, udev, NULL, 0, __func__);
>  	if (ret <= 0)
> @@ -946,17 +962,18 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
>  	virt_dev = xhci->devs[udev->slot_id];
>  
>  	/* See section 4.6.6 - A0 = 1; A1 = D0 = D1 = 0 */
> -	virt_dev->in_ctx->add_flags |= SLOT_FLAG;
> -	virt_dev->in_ctx->add_flags &= ~EP0_FLAG;
> -	virt_dev->in_ctx->drop_flags &= ~SLOT_FLAG;
> -	virt_dev->in_ctx->drop_flags &= ~EP0_FLAG;
> +	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
> +	ctrl_ctx->add_flags |= SLOT_FLAG;
> +	ctrl_ctx->add_flags &= ~EP0_FLAG;
> +	ctrl_ctx->drop_flags &= ~SLOT_FLAG;
> +	ctrl_ctx->drop_flags &= ~EP0_FLAG;
>  	xhci_dbg(xhci, "New Input Control Context:\n");
> -	xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma,
> -			LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info));
> +	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx);
> +	xhci_dbg_ctx(xhci, virt_dev->in_ctx,
> +			LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
>  
>  	spin_lock_irqsave(&xhci->lock, flags);
> -	/* 32 bytes of padding before input control context starts */
> -	ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx_dma + 32,
> +	ret = xhci_queue_configure_endpoint(xhci, virt_dev->in_ctx->dma,
>  			udev->slot_id);
>  	if (ret < 0) {
>  		spin_unlock_irqrestore(&xhci->lock, flags);
> @@ -1011,10 +1028,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
>  	}
>  
>  	xhci_dbg(xhci, "Output context after successful config ep cmd:\n");
> -	xhci_dbg_device_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma,
> -			LAST_CTX_TO_EP_NUM(virt_dev->in_ctx->slot.dev_info));
> +	xhci_dbg_ctx(xhci, virt_dev->out_ctx,
> +			LAST_CTX_TO_EP_NUM(slot_ctx->dev_info));
>  
> -	xhci_zero_in_ctx(virt_dev);
> +	xhci_zero_in_ctx(xhci, virt_dev);
>  	/* Free any old rings */
>  	for (i = 1; i < 31; ++i) {
>  		if (virt_dev->new_ep_rings[i]) {
> @@ -1052,7 +1069,7 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
>  			virt_dev->new_ep_rings[i] = NULL;
>  		}
>  	}
> -	xhci_zero_in_ctx(virt_dev);
> +	xhci_zero_in_ctx(xhci, virt_dev);
>  }
>  
>  /* Deal with stalled endpoints.  The core should have sent the control message
> @@ -1185,6 +1202,8 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
>  	struct xhci_virt_device *virt_dev;
>  	int ret = 0;
>  	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
> +	struct xhci_slot_ctx *slot_ctx;
> +	struct xhci_input_control_ctx *ctrl_ctx;
>  	u64 temp_64;
>  
>  	if (!udev->slot_id) {
> @@ -1200,9 +1219,8 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
>  	/* Otherwise, assume the core has the device configured how it wants */
>  
>  	spin_lock_irqsave(&xhci->lock, flags);
> -	/* 32 bytes of padding before input control context starts */
> -	ret = xhci_queue_address_device(xhci, virt_dev->in_ctx_dma + 32,
> -			udev->slot_id);
> +	ret = xhci_queue_address_device(xhci, virt_dev->in_ctx->dma,
> +					udev->slot_id);
>  	if (ret) {
>  		spin_unlock_irqrestore(&xhci->lock, flags);
>  		xhci_dbg(xhci, "FIXME: allocate a command ring segment\n");
> @@ -1256,19 +1274,21 @@ int xhci_address_device(struct usb_hcd *hcd, struct usb_device *udev)
>  			(unsigned long long)
>  				xhci->dcbaa->dev_context_ptrs[udev->slot_id]);
>  	xhci_dbg(xhci, "Output Context DMA address = %#08llx\n",
> -			(unsigned long long)virt_dev->out_ctx_dma);
> +			(unsigned long long)virt_dev->out_ctx->dma);
>  	xhci_dbg(xhci, "Slot ID %d Input Context:\n", udev->slot_id);
> -	xhci_dbg_ctx(xhci, virt_dev->in_ctx, virt_dev->in_ctx_dma, 2);
> +	xhci_dbg_ctx(xhci, virt_dev->in_ctx, 2);
>  	xhci_dbg(xhci, "Slot ID %d Output Context:\n", udev->slot_id);
> -	xhci_dbg_device_ctx(xhci, virt_dev->out_ctx, virt_dev->out_ctx_dma, 2);
> +	xhci_dbg_ctx(xhci, virt_dev->out_ctx, 2);
>  	/*
>  	 * USB core uses address 1 for the roothubs, so we add one to the
>  	 * address given back to us by the HC.
>  	 */
> -	udev->devnum = (virt_dev->out_ctx->slot.dev_state & DEV_ADDR_MASK) + 1;
> +	slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->out_ctx);
> +	udev->devnum = (slot_ctx->dev_state & DEV_ADDR_MASK) + 1;
>  	/* Zero the input context control for later use */
> -	virt_dev->in_ctx->add_flags = 0;
> -	virt_dev->in_ctx->drop_flags = 0;
> +	ctrl_ctx = xhci_get_input_control_ctx(xhci, virt_dev->in_ctx);
> +	ctrl_ctx->add_flags = 0;
> +	ctrl_ctx->drop_flags = 0;
>  
>  	xhci_dbg(xhci, "Device address = %d\n", udev->devnum);
>  	/* XXX Meh, not sure if anyone else but choose_address uses this. */
> @@ -1310,7 +1330,6 @@ static int __init xhci_hcd_init(void)
>  	/* xhci_device_control has eight fields, and also
>  	 * embeds one xhci_slot_ctx and 31 xhci_ep_ctx
>  	 */
> -	BUILD_BUG_ON(sizeof(struct xhci_device_control) != (8+8+8+8*31)*32/8);
>  	BUILD_BUG_ON(sizeof(struct xhci_stream_ctx) != 4*32/8);
>  	BUILD_BUG_ON(sizeof(union xhci_trb) != 4*32/8);
>  	BUILD_BUG_ON(sizeof(struct xhci_erst_entry) != 4*32/8);
> diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
> index d90baaa..44abe48 100644
> --- a/drivers/usb/host/xhci-mem.c
> +++ b/drivers/usb/host/xhci-mem.c
> @@ -189,6 +189,63 @@ fail:
>  	return 0;
>  }
>  
> +#define CTX_SIZE(_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32)
> +
> +struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhci,
> +						    int type, gfp_t flags)
> +{
> +	struct xhci_container_ctx *ctx = kzalloc(sizeof(*ctx), flags);
> +	if (!ctx)
> +		return NULL;
> +
> +	BUG_ON((type != XHCI_CTX_TYPE_DEVICE) && (type != XHCI_CTX_TYPE_INPUT));
> +	ctx->type = type;
> +	ctx->size = HCC_64BYTE_CONTEXT(xhci->hcc_params) ? 2048 : 1024;
> +	if (type == XHCI_CTX_TYPE_INPUT)
> +		ctx->size += CTX_SIZE(xhci->hcc_params);
> +
> +	ctx->bytes = dma_pool_alloc(xhci->device_pool, flags, &ctx->dma);
> +	memset(ctx->bytes, 0, ctx->size);
> +	return ctx;
> +}
> +
> +void xhci_free_container_ctx(struct xhci_hcd *xhci,
> +			     struct xhci_container_ctx *ctx)
> +{
> +	dma_pool_free(xhci->device_pool, ctx->bytes, ctx->dma);
> +	kfree(ctx);
> +}
> +
> +struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci,
> +					      struct xhci_container_ctx *ctx)
> +{
> +	BUG_ON(ctx->type != XHCI_CTX_TYPE_INPUT);
> +	return (struct xhci_input_control_ctx *)ctx->bytes;
> +}
> +
> +struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci,
> +					struct xhci_container_ctx *ctx)
> +{
> +	if (ctx->type == XHCI_CTX_TYPE_DEVICE)
> +		return (struct xhci_slot_ctx *)ctx->bytes;
> +
> +	return (struct xhci_slot_ctx *)
> +		(ctx->bytes + CTX_SIZE(xhci->hcc_params));
> +}
> +
> +struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci,
> +				    struct xhci_container_ctx *ctx,
> +				    unsigned int ep_index)
> +{
> +	/* increment ep index by offset of start of ep ctx array */
> +	ep_index++;
> +	if (ctx->type == XHCI_CTX_TYPE_INPUT)
> +		ep_index++;
> +
> +	return (struct xhci_ep_ctx *)
> +		(ctx->bytes + (ep_index * CTX_SIZE(xhci->hcc_params)));
> +}
> +
>  /* All the xhci_tds in the ring's TD list should be freed at this point */
>  void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
>  {
> @@ -209,11 +266,10 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
>  			xhci_ring_free(xhci, dev->ep_rings[i]);
>  
>  	if (dev->in_ctx)
> -		dma_pool_free(xhci->device_pool,
> -				dev->in_ctx, dev->in_ctx_dma);
> +		xhci_free_container_ctx(xhci, dev->in_ctx);
>  	if (dev->out_ctx)
> -		dma_pool_free(xhci->device_pool,
> -				dev->out_ctx, dev->out_ctx_dma);
> +		xhci_free_container_ctx(xhci, dev->out_ctx);
> +
>  	kfree(xhci->devs[slot_id]);
>  	xhci->devs[slot_id] = 0;
>  }
> @@ -221,7 +277,6 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
>  int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
>  		struct usb_device *udev, gfp_t flags)
>  {
> -	dma_addr_t	dma;
>  	struct xhci_virt_device *dev;
>  
>  	/* Slot ID 0 is reserved */
> @@ -235,26 +290,21 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
>  		return 0;
>  	dev = xhci->devs[slot_id];
>  
> -	/* Allocate the (output) device context that will be used in the HC.
> -	 * The structure is 64 bytes smaller than the input context, but that's
> -	 * fine.
> -	 */
> -	dev->out_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma);
> +	/* Allocate the (output) device context that will be used in the HC. */
> +	dev->out_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_DEVICE, flags);
>  	if (!dev->out_ctx)
>  		goto fail;
> -	dev->out_ctx_dma = dma;
> +
>  	xhci_dbg(xhci, "Slot %d output ctx = 0x%llx (dma)\n", slot_id,
> -			(unsigned long long)dma);
> -	memset(dev->out_ctx, 0, sizeof(*dev->out_ctx));
> +			(unsigned long long)dev->out_ctx->dma);
>  
>  	/* Allocate the (input) device context for address device command */
> -	dev->in_ctx = dma_pool_alloc(xhci->device_pool, flags, &dma);
> +	dev->in_ctx = xhci_alloc_container_ctx(xhci, XHCI_CTX_TYPE_INPUT, flags);
>  	if (!dev->in_ctx)
>  		goto fail;
> -	dev->in_ctx_dma = dma;
> +
>  	xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
> -			(unsigned long long)dma);
> -	memset(dev->in_ctx, 0, sizeof(*dev->in_ctx));
> +			(unsigned long long)dev->in_ctx->dma);
>  
>  	/* Allocate endpoint 0 ring */
>  	dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags);
> @@ -264,7 +314,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
>  	init_completion(&dev->cmd_completion);
>  
>  	/* Point to output device context in dcbaa. */
> -	xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx_dma;
> +	xhci->dcbaa->dev_context_ptrs[slot_id] = dev->out_ctx->dma;
>  	xhci_dbg(xhci, "Set slot id %d dcbaa entry %p to 0x%llx\n",
>  			slot_id,
>  			&xhci->dcbaa->dev_context_ptrs[slot_id],
> @@ -282,6 +332,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
>  	struct xhci_virt_device *dev;
>  	struct xhci_ep_ctx	*ep0_ctx;
>  	struct usb_device	*top_dev;
> +	struct xhci_slot_ctx    *slot_ctx;
> +	struct xhci_input_control_ctx *ctrl_ctx;
>  
>  	dev = xhci->devs[udev->slot_id];
>  	/* Slot ID 0 is reserved */
> @@ -290,27 +342,29 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
>  				udev->slot_id);
>  		return -EINVAL;
>  	}
> -	ep0_ctx = &dev->in_ctx->ep[0];
> +	ep0_ctx = xhci_get_ep_ctx(xhci, dev->in_ctx, 0);
> +	ctrl_ctx = xhci_get_input_control_ctx(xhci, dev->in_ctx);
> +	slot_ctx = xhci_get_slot_ctx(xhci, dev->in_ctx);
>  
>  	/* 2) New slot context and endpoint 0 context are valid*/
> -	dev->in_ctx->add_flags = SLOT_FLAG | EP0_FLAG;
> +	ctrl_ctx->add_flags = SLOT_FLAG | EP0_FLAG;
>  
>  	/* 3) Only the control endpoint is valid - one endpoint context */
> -	dev->in_ctx->slot.dev_info |= LAST_CTX(1);
> +	slot_ctx->dev_info |= LAST_CTX(1);
>  
>  	switch (udev->speed) {
>  	case USB_SPEED_SUPER:
> -		dev->in_ctx->slot.dev_info |= (u32) udev->route;
> -		dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_SS;
> +		slot_ctx->dev_info |= (u32) udev->route;
> +		slot_ctx->dev_info |= (u32) SLOT_SPEED_SS;
>  		break;
>  	case USB_SPEED_HIGH:
> -		dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_HS;
> +		slot_ctx->dev_info |= (u32) SLOT_SPEED_HS;
>  		break;
>  	case USB_SPEED_FULL:
> -		dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_FS;
> +		slot_ctx->dev_info |= (u32) SLOT_SPEED_FS;
>  		break;
>  	case USB_SPEED_LOW:
> -		dev->in_ctx->slot.dev_info |= (u32) SLOT_SPEED_LS;
> +		slot_ctx->dev_info |= (u32) SLOT_SPEED_LS;
>  		break;
>  	case USB_SPEED_VARIABLE:
>  		xhci_dbg(xhci, "FIXME xHCI doesn't support wireless speeds\n");
> @@ -324,7 +378,7 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
>  	for (top_dev = udev; top_dev->parent && top_dev->parent->parent;
>  			top_dev = top_dev->parent)
>  		/* Found device below root hub */;
> -	dev->in_ctx->slot.dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum);
> +	slot_ctx->dev_info2 |= (u32) ROOT_HUB_PORT(top_dev->portnum);
>  	xhci_dbg(xhci, "Set root hub portnum to %d\n", top_dev->portnum);
>  
>  	/* Is this a LS/FS device under a HS hub? */
> @@ -334,8 +388,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
>  	 */
>  	if ((udev->speed == USB_SPEED_LOW || udev->speed == USB_SPEED_FULL) &&
>  			udev->tt) {
> -		dev->in_ctx->slot.tt_info = udev->tt->hub->slot_id;
> -		dev->in_ctx->slot.tt_info |= udev->ttport << 8;
> +		slot_ctx->tt_info = udev->tt->hub->slot_id;
> +		slot_ctx->tt_info |= udev->ttport << 8;
>  	}
>  	xhci_dbg(xhci, "udev->tt = %p\n", udev->tt);
>  	xhci_dbg(xhci, "udev->ttport = 0x%x\n", udev->ttport);
> @@ -466,7 +520,7 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
>  	unsigned int max_burst;
>  
>  	ep_index = xhci_get_endpoint_index(&ep->desc);
> -	ep_ctx = &virt_dev->in_ctx->ep[ep_index];
> +	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
>  
>  	/* Set up the endpoint ring */
>  	virt_dev->new_ep_rings[ep_index] = xhci_ring_alloc(xhci, 1, true, mem_flags);
> @@ -533,7 +587,7 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
>  	struct xhci_ep_ctx *ep_ctx;
>  
>  	ep_index = xhci_get_endpoint_index(&ep->desc);
> -	ep_ctx = &virt_dev->in_ctx->ep[ep_index];
> +	ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index);
>  
>  	ep_ctx->ep_info = 0;
>  	ep_ctx->ep_info2 = 0;
> @@ -655,11 +709,10 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
>  	 */
>  	xhci->segment_pool = dma_pool_create("xHCI ring segments", dev,
>  			SEGMENT_SIZE, 64, xhci->page_size);
> +
>  	/* See Table 46 and Note on Figure 55 */
> -	/* FIXME support 64-byte contexts */
>  	xhci->device_pool = dma_pool_create("xHCI input/output contexts", dev,
> -			sizeof(struct xhci_device_control),
> -			64, xhci->page_size);
> +			2112, 64, xhci->page_size);
>  	if (!xhci->segment_pool || !xhci->device_pool)
>  		goto fail;
>  
> diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
> index 894f056..fb59dfd 100644
> --- a/drivers/usb/host/xhci-ring.c
> +++ b/drivers/usb/host/xhci-ring.c
> @@ -362,6 +362,7 @@ static void find_new_dequeue_state(struct xhci_hcd *xhci,
>  	struct xhci_virt_device *dev = xhci->devs[slot_id];
>  	struct xhci_ring *ep_ring = dev->ep_rings[ep_index];
>  	struct xhci_generic_trb *trb;
> +	struct xhci_ep_ctx *ep_ctx;
>  
>  	state->new_cycle_state = 0;
>  	state->new_deq_seg = find_trb_seg(cur_td->start_seg,
> @@ -370,7 +371,8 @@ static void find_new_dequeue_state(struct xhci_hcd *xhci,
>  	if (!state->new_deq_seg)
>  		BUG();
>  	/* Dig out the cycle state saved by the xHC during the stop ep cmd */
> -	state->new_cycle_state = 0x1 & dev->out_ctx->ep[ep_index].deq;
> +	ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
> +	state->new_cycle_state = 0x1 & ep_ctx->deq;
>  
>  	state->new_deq_ptr = cur_td->last_trb;
>  	state->new_deq_seg = find_trb_seg(state->new_deq_seg,
> @@ -570,11 +572,15 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
>  	unsigned int ep_index;
>  	struct xhci_ring *ep_ring;
>  	struct xhci_virt_device *dev;
> +	struct xhci_ep_ctx *ep_ctx;
> +	struct xhci_slot_ctx *slot_ctx;
>  
>  	slot_id = TRB_TO_SLOT_ID(trb->generic.field[3]);
>  	ep_index = TRB_TO_EP_INDEX(trb->generic.field[3]);
>  	dev = xhci->devs[slot_id];
>  	ep_ring = dev->ep_rings[ep_index];
> +	ep_ctx = xhci_get_ep_ctx(xhci, dev->out_ctx, ep_index);
> +	slot_ctx = xhci_get_slot_ctx(xhci, dev->out_ctx);
>  
>  	if (GET_COMP_CODE(event->status) != COMP_SUCCESS) {
>  		unsigned int ep_state;
> @@ -588,9 +594,9 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
>  		case COMP_CTX_STATE:
>  			xhci_warn(xhci, "WARN Set TR Deq Ptr cmd failed due "
>  					"to incorrect slot or ep state.\n");
> -			ep_state = dev->out_ctx->ep[ep_index].ep_info;
> +			ep_state = ep_ctx->ep_info;
>  			ep_state &= EP_STATE_MASK;
> -			slot_state = dev->out_ctx->slot.dev_state;
> +			slot_state = slot_ctx->dev_state;
>  			slot_state = GET_SLOT_STATE(slot_state);
>  			xhci_dbg(xhci, "Slot state = %u, EP state = %u\n",
>  					slot_state, ep_state);
> @@ -613,7 +619,7 @@ static void handle_set_deq_completion(struct xhci_hcd *xhci,
>  		 */
>  	} else {
>  		xhci_dbg(xhci, "Successful Set TR Deq Ptr cmd, deq = @%08llx\n",
> -				dev->out_ctx->ep[ep_index].deq);
> +				ep_ctx->deq);
>  	}
>  
>  	ep_ring->state &= ~SET_DEQ_PENDING;
> @@ -800,6 +806,7 @@ static int handle_tx_event(struct xhci_hcd *xhci,
>  	union xhci_trb *event_trb;
>  	struct urb *urb = 0;
>  	int status = -EINPROGRESS;
> +	struct xhci_ep_ctx *ep_ctx;
>  
>  	xhci_dbg(xhci, "In %s\n", __func__);
>  	xdev = xhci->devs[TRB_TO_SLOT_ID(event->flags)];
> @@ -812,7 +819,8 @@ static int handle_tx_event(struct xhci_hcd *xhci,
>  	ep_index = TRB_TO_EP_ID(event->flags) - 1;
>  	xhci_dbg(xhci, "%s - ep index = %d\n", __func__, ep_index);
>  	ep_ring = xdev->ep_rings[ep_index];
> -	if (!ep_ring || (xdev->out_ctx->ep[ep_index].ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
> +	ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
> +	if (!ep_ring || (ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED) {
>  		xhci_err(xhci, "ERROR Transfer event pointed to disabled endpoint\n");
>  		return -ENODEV;
>  	}
> @@ -1198,9 +1206,9 @@ static int prepare_transfer(struct xhci_hcd *xhci,
>  		gfp_t mem_flags)
>  {
>  	int ret;
> -
> +	struct xhci_ep_ctx *ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
>  	ret = prepare_ring(xhci, xdev->ep_rings[ep_index],
> -			xdev->out_ctx->ep[ep_index].ep_info & EP_STATE_MASK,
> +			ep_ctx->ep_info & EP_STATE_MASK,
>  			num_trbs, mem_flags);
>  	if (ret)
>  		return ret;
> diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
> index 341c907..a36ac2a 100644
> --- a/drivers/usb/host/xhci.h
> +++ b/drivers/usb/host/xhci.h
> @@ -446,6 +446,27 @@ struct xhci_doorbell_array {
>  
>  
>  /**
> + * struct xhci_container_ctx
> + * @type: Type of context.  Used to calculated offsets to contained contexts.
> + * @size: Size of the context data
> + * @bytes: The raw context data given to HW
> + * @dma: dma address of the bytes
> + *
> + * Represents either a Device or Input context.  Holds a pointer to the raw
> + * memory used for the context (bytes) and dma address of it (dma).
> + */
> +struct xhci_container_ctx {
> +	unsigned type;
> +#define XHCI_CTX_TYPE_DEVICE  0x1
> +#define XHCI_CTX_TYPE_INPUT   0x2
> +
> +	int size;
> +
> +	u8 *bytes;
> +	dma_addr_t dma;
> +};
> +
> +/**
>   * struct xhci_slot_ctx
>   * @dev_info:	Route string, device speed, hub info, and last valid endpoint
>   * @dev_info2:	Max exit latency for device number, root hub port number
> @@ -582,35 +603,16 @@ struct xhci_ep_ctx {
>  
>  
>  /**
> - * struct xhci_device_control
> - * Input context; see section 6.2.5.
> + * struct xhci_input_control_context
> + * Input control context; see section 6.2.5.
>   *
>   * @drop_context:	set the bit of the endpoint context you want to disable
>   * @add_context:	set the bit of the endpoint context you want to enable
>   */
> -struct xhci_device_control {
> -	/* Device contexts must be 64-byte aligned, so add 32-bytes of padding
> -	 * before the 32-bytes control context */
> -	u32	rsvd1[8];
> -	/* Input control context */
> +struct xhci_input_control_ctx {
>  	u32	drop_flags;
>  	u32	add_flags;
>  	u32	rsvd2[6];
> -	/* Device context */
> -	struct xhci_slot_ctx	slot;
> -	struct xhci_ep_ctx	ep[31];
> -};
> -
> -/**
> - * struct xhci_device_ctx
> - * Device context; see section 6.2.1.
> - *
> - * @slot:		slot context for the device.
> - * @ep:			array of endpoint contexts for the device.
> - */
> -struct xhci_device_ctx {
> -	struct xhci_slot_ctx	slot;
> -	struct xhci_ep_ctx	ep[31];
>  };
>  
>  /* drop context bitmasks */
> @@ -618,7 +620,6 @@ struct xhci_device_ctx {
>  /* add context bitmasks */
>  #define	ADD_EP(x)	(0x1 << x)
>  
> -
>  struct xhci_virt_device {
>  	/*
>  	 * Commands to the hardware are passed an "input context" that
> @@ -628,11 +629,10 @@ struct xhci_virt_device {
>  	 * track of input and output contexts separately because
>  	 * these commands might fail and we don't trust the hardware.
>  	 */
> -	struct xhci_device_ctx		*out_ctx;
> -	dma_addr_t			out_ctx_dma;
> +	struct xhci_container_ctx       *out_ctx;
>  	/* Used for addressing devices and configuration changes */
> -	struct xhci_device_control	*in_ctx;
> -	dma_addr_t			in_ctx_dma;
> +	struct xhci_container_ctx       *in_ctx;
> +
>  	/* FIXME when stream support is added */
>  	struct xhci_ring		*ep_rings[31];
>  	/* Temporary storage in case the configure endpoint command fails and we
> @@ -1133,8 +1133,7 @@ void xhci_debug_ring(struct xhci_hcd *xhci, struct xhci_ring *ring);
>  void xhci_dbg_erst(struct xhci_hcd *xhci, struct xhci_erst *erst);
>  void xhci_dbg_cmd_ptrs(struct xhci_hcd *xhci);
>  void xhci_dbg_ring_ptrs(struct xhci_hcd *xhci, struct xhci_ring *ring);
> -void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_device_control *ctx, dma_addr_t dma, unsigned int last_ep);
> -void xhci_dbg_device_ctx(struct xhci_hcd *xhci, struct xhci_device_ctx *ctx, dma_addr_t dma, unsigned int last_ep);
> +void xhci_dbg_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int last_ep);
>  
>  /* xHCI memory managment */
>  void xhci_mem_cleanup(struct xhci_hcd *xhci);
> @@ -1201,4 +1200,9 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,
>  		char *buf, u16 wLength);
>  int xhci_hub_status_data(struct usb_hcd *hcd, char *buf);
>  
> +/* xHCI contexts */
> +struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
> +struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx);
> +struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index);
> +
>  #endif /* __LINUX_XHCI_HCD_H */
> -- 
> 1.6.2.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux