aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-hcd.c88
-rw-r--r--drivers/usb/host/xhci-ring.c4
-rw-r--r--drivers/usb/host/xhci.h2
3 files changed, 89 insertions, 5 deletions
diff --git a/drivers/usb/host/xhci-hcd.c b/drivers/usb/host/xhci-hcd.c
index ddb1a6a118eb..4e18f4edf5aa 100644
--- a/drivers/usb/host/xhci-hcd.c
+++ b/drivers/usb/host/xhci-hcd.c
@@ -601,6 +601,70 @@ int xhci_check_args(struct usb_hcd *hcd, struct usb_device *udev,
601 return 1; 601 return 1;
602} 602}
603 603
604static int xhci_configure_endpoint(struct xhci_hcd *xhci,
605 struct usb_device *udev, struct xhci_virt_device *virt_dev,
606 bool ctx_change);
607
608/*
609 * Full speed devices may have a max packet size greater than 8 bytes, but the
610 * USB core doesn't know that until it reads the first 8 bytes of the
611 * descriptor. If the usb_device's max packet size changes after that point,
612 * we need to issue an evaluate context command and wait on it.
613 */
614static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id,
615 unsigned int ep_index, struct urb *urb)
616{
617 struct xhci_container_ctx *in_ctx;
618 struct xhci_container_ctx *out_ctx;
619 struct xhci_input_control_ctx *ctrl_ctx;
620 struct xhci_ep_ctx *ep_ctx;
621 int max_packet_size;
622 int hw_max_packet_size;
623 int ret = 0;
624
625 out_ctx = xhci->devs[slot_id]->out_ctx;
626 ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
627 hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2);
628 max_packet_size = urb->dev->ep0.desc.wMaxPacketSize;
629 if (hw_max_packet_size != max_packet_size) {
630 xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n");
631 xhci_dbg(xhci, "Max packet size in usb_device = %d\n",
632 max_packet_size);
633 xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n",
634 hw_max_packet_size);
635 xhci_dbg(xhci, "Issuing evaluate context command.\n");
636
637 /* Set up the modified control endpoint 0 */
638 xhci_endpoint_copy(xhci, xhci->devs[slot_id], ep_index);
639 in_ctx = xhci->devs[slot_id]->in_ctx;
640 ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index);
641 ep_ctx->ep_info2 &= ~MAX_PACKET_MASK;
642 ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size);
643
644 /* Set up the input context flags for the command */
645 /* FIXME: This won't work if a non-default control endpoint
646 * changes max packet sizes.
647 */
648 ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
649 ctrl_ctx->add_flags = EP0_FLAG;
650 ctrl_ctx->drop_flags = 0;
651
652 xhci_dbg(xhci, "Slot %d input context\n", slot_id);
653 xhci_dbg_ctx(xhci, in_ctx, ep_index);
654 xhci_dbg(xhci, "Slot %d output context\n", slot_id);
655 xhci_dbg_ctx(xhci, out_ctx, ep_index);
656
657 ret = xhci_configure_endpoint(xhci, urb->dev,
658 xhci->devs[slot_id], true);
659
660 /* Clean up the input context for later use by bandwidth
661 * functions.
662 */
663 ctrl_ctx->add_flags = SLOT_FLAG;
664 }
665 return ret;
666}
667
604/* 668/*
605 * non-error returns are a promise to giveback() the urb later 669 * non-error returns are a promise to giveback() the urb later
606 * we drop ownership so next owner (or urb unlink) can get it 670 * we drop ownership so next owner (or urb unlink) can get it
@@ -612,13 +676,13 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
612 int ret = 0; 676 int ret = 0;
613 unsigned int slot_id, ep_index; 677 unsigned int slot_id, ep_index;
614 678
679
615 if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) 680 if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0)
616 return -EINVAL; 681 return -EINVAL;
617 682
618 slot_id = urb->dev->slot_id; 683 slot_id = urb->dev->slot_id;
619 ep_index = xhci_get_endpoint_index(&urb->ep->desc); 684 ep_index = xhci_get_endpoint_index(&urb->ep->desc);
620 685
621 spin_lock_irqsave(&xhci->lock, flags);
622 if (!xhci->devs || !xhci->devs[slot_id]) { 686 if (!xhci->devs || !xhci->devs[slot_id]) {
623 if (!in_interrupt()) 687 if (!in_interrupt())
624 dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); 688 dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n");
@@ -631,19 +695,33 @@ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags)
631 ret = -ESHUTDOWN; 695 ret = -ESHUTDOWN;
632 goto exit; 696 goto exit;
633 } 697 }
634 if (usb_endpoint_xfer_control(&urb->ep->desc)) 698 if (usb_endpoint_xfer_control(&urb->ep->desc)) {
699 /* Check to see if the max packet size for the default control
700 * endpoint changed during FS device enumeration
701 */
702 if (urb->dev->speed == USB_SPEED_FULL) {
703 ret = xhci_check_maxpacket(xhci, slot_id,
704 ep_index, urb);
705 if (ret < 0)
706 return ret;
707 }
708
635 /* We have a spinlock and interrupts disabled, so we must pass 709 /* We have a spinlock and interrupts disabled, so we must pass
636 * atomic context to this function, which may allocate memory. 710 * atomic context to this function, which may allocate memory.
637 */ 711 */
712 spin_lock_irqsave(&xhci->lock, flags);
638 ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, 713 ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb,
639 slot_id, ep_index); 714 slot_id, ep_index);
640 else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) 715 spin_unlock_irqrestore(&xhci->lock, flags);
716 } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) {
717 spin_lock_irqsave(&xhci->lock, flags);
641 ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, 718 ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb,
642 slot_id, ep_index); 719 slot_id, ep_index);
643 else 720 spin_unlock_irqrestore(&xhci->lock, flags);
721 } else {
644 ret = -EINVAL; 722 ret = -EINVAL;
723 }
645exit: 724exit:
646 spin_unlock_irqrestore(&xhci->lock, flags);
647 return ret; 725 return ret;
648} 726}
649 727
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index ac5c662368ed..ee7fc4500dfb 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -701,6 +701,10 @@ static void handle_cmd_completion(struct xhci_hcd *xhci,
701 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); 701 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status);
702 complete(&xhci->devs[slot_id]->cmd_completion); 702 complete(&xhci->devs[slot_id]->cmd_completion);
703 break; 703 break;
704 case TRB_TYPE(TRB_EVAL_CONTEXT):
705 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status);
706 complete(&xhci->devs[slot_id]->cmd_completion);
707 break;
704 case TRB_TYPE(TRB_ADDR_DEV): 708 case TRB_TYPE(TRB_ADDR_DEV):
705 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status); 709 xhci->devs[slot_id]->cmd_status = GET_COMP_CODE(event->status);
706 complete(&xhci->addr_dev); 710 complete(&xhci->addr_dev);
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index a8fe21762052..6aecede77ff6 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -601,6 +601,8 @@ struct xhci_ep_ctx {
601/* bit 7 is Host Initiate Disable - for disabling stream selection */ 601/* bit 7 is Host Initiate Disable - for disabling stream selection */
602#define MAX_BURST(p) (((p)&0xff) << 8) 602#define MAX_BURST(p) (((p)&0xff) << 8)
603#define MAX_PACKET(p) (((p)&0xffff) << 16) 603#define MAX_PACKET(p) (((p)&0xffff) << 16)
604#define MAX_PACKET_MASK (0xffff << 16)
605#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
604 606
605 607
606/** 608/**