void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct xhci_dequeue_state *deq_state) { struct xhci_container_ctx *in_ctx; struct xhci_ep_ctx *ep_ctx; u32 added_ctxs; dma_addr_t addr; xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, xhci->devs[slot_id]->out_ctx, ep_index); in_ctx = xhci->devs[slot_id]->in_ctx; ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); addr = xhci_trb_virt_to_dma(deq_state->new_deq_seg, deq_state->new_deq_ptr); if (addr == 0) { xhci_warn(xhci, "WARN Cannot submit config ep after " "reset ep command\n"); xhci_warn(xhci, "WARN deq seg = %p, deq ptr = %p\n", deq_state->new_deq_seg, deq_state->new_deq_ptr); return; } ep_ctx->deq = addr | deq_state->new_cycle_state; added_ctxs = xhci_get_endpoint_flag_from_index(ep_index); xhci_setup_input_ctx_for_config_ep(xhci, xhci->devs[slot_id]->in_ctx, xhci->devs[slot_id]->out_ctx, added_ctxs, added_ctxs); }
static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct urb *urb) { struct xhci_container_ctx *in_ctx; struct xhci_container_ctx *out_ctx; struct xhci_input_control_ctx *ctrl_ctx; struct xhci_ep_ctx *ep_ctx; int max_packet_size; int hw_max_packet_size; int ret = 0; out_ctx = xhci->devs[slot_id]->out_ctx; ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); hw_max_packet_size = MAX_PACKET_DECODED(ep_ctx->ep_info2); max_packet_size = urb->dev->ep0.desc.wMaxPacketSize; if (hw_max_packet_size != max_packet_size) { xhci_dbg(xhci, "Max Packet Size for ep 0 changed.\n"); xhci_dbg(xhci, "Max packet size in usb_device = %d\n", max_packet_size); xhci_dbg(xhci, "Max packet size in xHCI HW = %d\n", hw_max_packet_size); xhci_dbg(xhci, "Issuing evaluate context command.\n"); xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, xhci->devs[slot_id]->out_ctx, ep_index); in_ctx = xhci->devs[slot_id]->in_ctx; ep_ctx = xhci_get_ep_ctx(xhci, in_ctx, ep_index); ep_ctx->ep_info2 &= ~MAX_PACKET_MASK; ep_ctx->ep_info2 |= MAX_PACKET(max_packet_size); ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); ctrl_ctx->add_flags = EP0_FLAG; ctrl_ctx->drop_flags = 0; xhci_dbg(xhci, "Slot %d input context\n", slot_id); xhci_dbg_ctx(xhci, in_ctx, ep_index); xhci_dbg(xhci, "Slot %d output context\n", slot_id); xhci_dbg_ctx(xhci, out_ctx, ep_index); ret = xhci_configure_endpoint(xhci, urb->dev, NULL, true, false); ctrl_ctx->add_flags = SLOT_FLAG; } return ret; }
/* * Full speed devices may have a max packet size greater than 8 bytes, but the * USB core doesn't know that until it reads the first 8 bytes of the * descriptor. If the usb_device's max packet size changes after that point, * we need to issue an evaluate context command and wait on it. */ static int xhci_check_maxpacket(struct xhci_hcd *xhci, unsigned int slot_id, unsigned int ep_index, struct urb *urb) { struct xhci_container_ctx *out_ctx; struct xhci_input_control_ctx *ctrl_ctx; struct xhci_ep_ctx *ep_ctx; struct xhci_command *command; int max_packet_size; int hw_max_packet_size; int ret = 0; out_ctx = xhci->devs[slot_id]->out_ctx; ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); hw_max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); max_packet_size = usb_endpoint_maxp(&urb->dev->ep0.desc); if (hw_max_packet_size != max_packet_size) { xhci_dbg_trace(xhci, trace_xhci_dbg_context_change, "Max Packet Size for ep 0 changed."); xhci_dbg_trace(xhci, trace_xhci_dbg_context_change, "Max packet size in usb_device = %d", max_packet_size); xhci_dbg_trace(xhci, trace_xhci_dbg_context_change, "Max packet size in xHCI HW = %d", hw_max_packet_size); xhci_dbg_trace(xhci, trace_xhci_dbg_context_change, "Issuing evaluate context command."); /* Set up the input context flags for the command */ /* FIXME: This won't work if a non-default control endpoint * changes max packet sizes. */ command = xhci_alloc_command(xhci, false, true, GFP_KERNEL); if (!command) return -ENOMEM; command->in_ctx = xhci->devs[slot_id]->in_ctx; ctrl_ctx = xhci_get_input_control_ctx(command->in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); ret = -ENOMEM; goto command_cleanup; } /* Set up the modified control endpoint 0 */ xhci_endpoint_copy(xhci, xhci->devs[slot_id]->in_ctx, xhci->devs[slot_id]->out_ctx, ep_index); ep_ctx = xhci_get_ep_ctx(xhci, command->in_ctx, ep_index); ep_ctx->ep_info2 &= cpu_to_le32(~MAX_PACKET_MASK); ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size)); ctrl_ctx->add_flags = cpu_to_le32(EP0_FLAG); ctrl_ctx->drop_flags = 0; xhci_dbg(xhci, "Slot %d input context\n", slot_id); xhci_dbg_ctx(xhci, command->in_ctx, ep_index); xhci_dbg(xhci, "Slot %d output context\n", slot_id); xhci_dbg_ctx(xhci, out_ctx, ep_index); ret = xhci_configure_endpoint(xhci, urb->dev, command, true, false); /* Clean up the input context for later use by bandwidth * functions. */ ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG); command_cleanup: kfree(command->completion); kfree(command); } return ret; }