int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); unsigned long flags; int ret = 0; unsigned int slot_id, ep_index; if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) return -EINVAL; slot_id = urb->dev->slot_id; ep_index = xhci_get_endpoint_index(&urb->ep->desc); if (!xhci->devs || !xhci->devs[slot_id]) { if (!in_interrupt()) dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); ret = -EINVAL; goto exit; } if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { if (!in_interrupt()) xhci_dbg(xhci, "urb submitted during PCI suspend\n"); ret = -ESHUTDOWN; goto exit; } if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (urb->dev->speed == USB_SPEED_FULL) { ret = xhci_check_maxpacket(xhci, slot_id, ep_index, urb); if (ret < 0) return ret; } spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); spin_unlock_irqrestore(&xhci->lock, flags); } else { ret = -EINVAL; } exit: return ret; }
/* Drop an endpoint from a new bandwidth configuration for this device. * Only one call to this function is allowed per endpoint before * check_bandwidth() or reset_bandwidth() must be called. * A call to xhci_drop_endpoint() followed by a call to xhci_add_endpoint() will * add the endpoint to the schedule with possibly new parameters denoted by a * different endpoint descriptor in usb_host_endpoint. * A call to xhci_add_endpoint() followed by a call to xhci_drop_endpoint() is * not allowed. * * The USB core will not allow URBs to be queued to an endpoint that is being * disabled, so there's no need for mutual exclusion to protect * the xhci->devs[slot_id] structure. */ int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; struct xhci_container_ctx *in_ctx, *out_ctx; struct xhci_input_control_ctx *ctrl_ctx; unsigned int ep_index; struct xhci_ep_ctx *ep_ctx; u32 drop_flag; u32 new_add_flags, new_drop_flags; int ret; ret = xhci_check_args(hcd, udev, ep, 1, true, __func__); if (ret <= 0) return ret; xhci = hcd_to_xhci(hcd); if (xhci->xhc_state & XHCI_STATE_DYING) return -ENODEV; xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); drop_flag = xhci_get_endpoint_flag(&ep->desc); if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", __func__, drop_flag); return 0; } 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(in_ctx); if (!ctrl_ctx) { xhci_warn(xhci, "%s: Could not get input context, bad type.\n", __func__); return 0; } ep_index = xhci_get_endpoint_index(&ep->desc); 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 & cpu_to_le32(EP_STATE_MASK)) == cpu_to_le32(EP_STATE_DISABLED)) || le32_to_cpu(ctrl_ctx->drop_flags) & xhci_get_endpoint_flag(&ep->desc)) { /* Do not warn when called after a usb_device_reset */ if (xhci->devs[udev->slot_id]->eps[ep_index].ring != NULL) xhci_warn(xhci, "xHCI %s called with disabled ep %p\n", __func__, ep); return 0; } ctrl_ctx->drop_flags |= cpu_to_le32(drop_flag); new_drop_flags = le32_t
int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { unsigned long flags; int ret; u32 temp; struct xhci_hcd *xhci; struct xhci_td *td; unsigned int ep_index; struct xhci_ring *ep_ring; struct xhci_virt_ep *ep; xhci = hcd_to_xhci(hcd); spin_lock_irqsave(&xhci->lock, flags); ret = usb_hcd_check_unlink_urb(hcd, urb, status); if (ret || !urb->hcpriv) goto done; temp = xhci_readl(xhci, &xhci->op_regs->status); if (temp == 0xffffffff) { xhci_dbg(xhci, "HW died, freeing TD.\n"); td = (struct xhci_td *) urb->hcpriv; usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock_irqrestore(&xhci->lock, flags); usb_hcd_giveback_urb(xhci_to_hcd(xhci), urb, -ESHUTDOWN); kfree(td); return ret; } xhci_dbg(xhci, "Cancel URB %p\n", urb); xhci_dbg(xhci, "Event ring:\n"); xhci_debug_ring(xhci, xhci->event_ring); ep_index = xhci_get_endpoint_index(&urb->ep->desc); ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; ep_ring = ep->ring; xhci_dbg(xhci, "Endpoint ring:\n"); xhci_debug_ring(xhci, ep_ring); td = (struct xhci_td *) urb->hcpriv; ep->cancels_pending++; list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); if (ep->cancels_pending == 1) { xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index); xhci_ring_cmd_db(xhci); } done: spin_unlock_irqrestore(&xhci->lock, flags); return ret; }
void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; struct usb_device *udev; unsigned int ep_index; unsigned long flags; int ret; struct xhci_virt_ep *virt_ep; xhci = hcd_to_xhci(hcd); udev = (struct usb_device *) ep->hcpriv; if (!ep->hcpriv) return; ep_index = xhci_get_endpoint_index(&ep->desc); virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; if (!virt_ep->stopped_td) { xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", ep->desc.bEndpointAddress); return; } if (usb_endpoint_xfer_control(&ep->desc)) { xhci_dbg(xhci, "Control endpoint stall already handled.\n"); return; } xhci_dbg(xhci, "Queueing reset endpoint command\n"); spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); if (!ret) { xhci_cleanup_stalled_ring(xhci, udev, ep_index); kfree(virt_ep->stopped_td); xhci_ring_cmd_db(xhci); } spin_unlock_irqrestore(&xhci->lock, flags); if (ret) xhci_warn(xhci, "FIXME allocate a new ring segment\n"); }
/* Get the right ring for the given URB. * If the endpoint supports streams, boundary check the URB's stream ID. * If the endpoint doesn't support streams, return the singular endpoint ring. */ static struct xhci_ring *xhci_urb_to_transfer_ring(struct xhci_hcd *xhci, struct urb *urb) { unsigned int slot_id; unsigned int ep_index; unsigned int stream_id; struct xhci_virt_ep *ep; slot_id = urb->dev->slot_id; ep_index = xhci_get_endpoint_index(&urb->ep->desc); stream_id = urb->stream_id; ep = &xhci->devs[slot_id]->eps[ep_index]; /* Common case: no streams */ if (!(ep->ep_state & EP_HAS_STREAMS)) return ep->ring; if (stream_id == 0) { xhci_warn(xhci, "WARN: Slot ID %u, ep index %u has streams, " "but URB has no stream ID.\n", slot_id, ep_index); return NULL; } if (stream_id < ep->stream_info->num_streams) return ep->stream_info->stream_rings[stream_id]; xhci_warn(xhci, "WARN: Slot ID %u, ep index %u has " "stream IDs 1 to %u allocated, " "but stream ID %u is requested.\n", slot_id, ep_index, ep->stream_info->num_streams - 1, stream_id); return NULL; }
/* * Remove the URB's TD from the endpoint ring. This may cause the HC to stop * USB transfers, potentially stopping in the middle of a TRB buffer. The HC * should pick up where it left off in the TD, unless a Set Transfer Ring * Dequeue Pointer is issued. * * The TRBs that make up the buffers for the canceled URB will be "removed" from * the ring. Since the ring is a contiguous structure, they can't be physically * removed. Instead, there are two options: * * 1) If the HC is in the middle of processing the URB to be canceled, we * simply move the ring's dequeue pointer past those TRBs using the Set * Transfer Ring Dequeue Pointer command. This will be the common case, * when drivers timeout on the last submitted URB and attempt to cancel. * * 2) If the HC is in the middle of a different TD, we turn the TRBs into a * series of 1-TRB transfer no-op TDs. (No-ops shouldn't be chained.) The * HC will need to invalidate the any TRBs it has cached after the stop * endpoint command, as noted in the xHCI 0.95 errata. * * 3) The TD may have completed by the time the Stop Endpoint Command * completes, so software needs to handle that case too. * * This function should protect against the TD enqueueing code ringing the * doorbell while this code is waiting for a Stop Endpoint command to complete. * It also needs to account for multiple cancellations on happening at the same * time for the same endpoint. * * Note that this function can be called in any context, or so says * usb_hcd_unlink_urb() */ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) { unsigned long flags; int ret, i; u32 temp; struct xhci_hcd *xhci; struct urb_priv *urb_priv; struct xhci_td *td; unsigned int ep_index; struct xhci_ring *ep_ring; struct xhci_virt_ep *ep; struct xhci_command *command; xhci = hcd_to_xhci(hcd); spin_lock_irqsave(&xhci->lock, flags); /* Make sure the URB hasn't completed or been unlinked already */ ret = usb_hcd_check_unlink_urb(hcd, urb, status); if (ret || !urb->hcpriv) goto done; temp = readl(&xhci->op_regs->status); if (temp == 0xffffffff || (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "HW died, freeing TD."); urb_priv = urb->hcpriv; for (i = urb_priv->td_cnt; i < urb_priv->length; i++) { td = urb_priv->td[i]; if (!list_empty(&td->td_list)) list_del_init(&td->td_list); if (!list_empty(&td->cancelled_td_list)) list_del_init(&td->cancelled_td_list); } usb_hcd_unlink_urb_from_ep(hcd, urb); spin_unlock_irqrestore(&xhci->lock, flags); usb_hcd_giveback_urb(hcd, urb, -ESHUTDOWN); xhci_urb_free_priv(urb_priv); return ret; } if ((xhci->xhc_state & XHCI_STATE_DYING) || (xhci->xhc_state & XHCI_STATE_HALTED)) { xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Ep 0x%x: URB %p to be canceled on " "non-responsive xHCI host.", urb->ep->desc.bEndpointAddress, urb); /* Let the stop endpoint command watchdog timer (which set this * state) finish cleaning up the endpoint TD lists. We must * have caught it in the middle of dropping a lock and giving * back an URB. */ goto done; } ep_index = xhci_get_endpoint_index(&urb->ep->desc); ep = &xhci->devs[urb->dev->slot_id]->eps[ep_index]; ep_ring = xhci_urb_to_transfer_ring(xhci, urb); if (!ep_ring) { ret = -EINVAL; goto done; } urb_priv = urb->hcpriv; i = urb_priv->td_cnt; if (i < urb_priv->length) xhci_dbg_trace(xhci, trace_xhci_dbg_cancel_urb, "Cancel URB %p, dev %s, ep 0x%x, " "starting at offset 0x%llx", urb, urb->dev->devpath, urb->ep->desc.bEndpointAddress, (unsigned long long) xhci_trb_virt_to_dma( urb_priv->td[i]->start_seg, urb_priv->td[i]->first_trb)); for (; i < urb_priv->length; i++) { td = urb_priv->td[i]; list_add_tail(&td->cancelled_td_list, &ep->cancelled_td_list); } /* Queue a stop endpoint command, but only if this is * the first cancellation to be handled. */ if (!(ep->ep_state & EP_HALT_PENDING)) { command = xhci_alloc_command(xhci, false, false, GFP_ATOMIC); if (!command) { ret = -ENOMEM; goto done; } ep->ep_state |= EP_HALT_PENDING; ep->stop_cmds_pending++; ep->stop_cmd_timer.expires = jiffies + XHCI_STOP_EP_CMD_TIMEOUT * HZ; add_timer(&ep->stop_cmd_timer); xhci_queue_stop_endpoint(xhci, command, urb->dev->slot_id, ep_index, 0); xhci_ring_cmd_db(xhci); } done: spin_unlock_irqrestore(&xhci->lock, flags); return ret; }
/* * non-error returns are a promise to giveback() the urb later * we drop ownership so next owner (or urb unlink) can get it */ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_td *buffer; unsigned long flags; int ret = 0; unsigned int slot_id, ep_index; struct urb_priv *urb_priv; int size, i; if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, true, __func__) <= 0) return -EINVAL; slot_id = urb->dev->slot_id; ep_index = xhci_get_endpoint_index(&urb->ep->desc); if (!HCD_HW_ACCESSIBLE(hcd)) { if (!in_interrupt()) xhci_dbg(xhci, "urb submitted during PCI suspend\n"); ret = -ESHUTDOWN; goto exit; } if (usb_endpoint_xfer_isoc(&urb->ep->desc)) size = urb->number_of_packets; else size = 1; urb_priv = kzalloc(sizeof(struct urb_priv) + size * sizeof(struct xhci_td *), mem_flags); if (!urb_priv) return -ENOMEM; buffer = kzalloc(size * sizeof(struct xhci_td), mem_flags); if (!buffer) { kfree(urb_priv); return -ENOMEM; } for (i = 0; i < size; i++) { urb_priv->td[i] = buffer; buffer++; } urb_priv->length = size; urb_priv->td_cnt = 0; urb->hcpriv = urb_priv; if (usb_endpoint_xfer_control(&urb->ep->desc)) { /* Check to see if the max packet size for the default control * endpoint changed during FS device enumeration */ if (urb->dev->speed == USB_SPEED_FULL) { ret = xhci_check_maxpacket(xhci, slot_id, ep_index, urb); if (ret < 0) { xhci_urb_free_priv(urb_priv); urb->hcpriv = NULL; return ret; } } /* We have a spinlock and interrupts disabled, so we must pass * atomic context to this function, which may allocate memory. */ spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_GETTING_STREAMS) { xhci_warn(xhci, "WARN: Can't enqueue URB while bulk ep " "is transitioning to using streams.\n"); ret = -EINVAL; } else if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_GETTING_NO_STREAMS) { xhci_warn(xhci, "WARN: Can't enqueue URB while bulk ep " "is transitioning to " "not having streams.\n"); ret = -EINVAL; } else { ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else { spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb, slot_id, ep_index); if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } exit: return ret; dying: xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " "non-responsive xHCI host.\n", urb->ep->desc.bEndpointAddress, urb); ret = -ESHUTDOWN; free_priv: xhci_urb_free_priv(urb_priv); urb->hcpriv = NULL; spin_unlock_irqrestore(&xhci->lock, flags); return ret; }
/* Find the flag for this endpoint (for use in the control context). Use the * endpoint index to create a bitmask. The slot context is bit 0, endpoint 0 is * bit 1, etc. */ unsigned int xhci_get_endpoint_flag(struct usb_endpoint_descriptor *desc) { return 1 << (xhci_get_endpoint_index(desc) + 1); }
int xhci_endpoint_init(struct xhci_hcd *xhci, struct xhci_virt_device *virt_dev, struct usb_device *udev, struct usb_host_endpoint *ep, gfp_t mem_flags) { unsigned int ep_index; struct xhci_ep_ctx *ep_ctx; struct xhci_ring *ep_ring; unsigned int max_packet; unsigned int max_burst; ep_index = xhci_get_endpoint_index(&ep->desc); ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); /* Set up the endpoint ring */ virt_dev->eps[ep_index].new_ring = xhci_ring_alloc(xhci, 1, true, mem_flags); if (!virt_dev->eps[ep_index].new_ring) { /* Attempt to use the ring cache */ if (virt_dev->num_rings_cached == 0) return -ENOMEM; virt_dev->eps[ep_index].new_ring = virt_dev->ring_cache[virt_dev->num_rings_cached]; virt_dev->ring_cache[virt_dev->num_rings_cached] = NULL; virt_dev->num_rings_cached--; xhci_reinit_cached_ring(xhci, virt_dev->eps[ep_index].new_ring); } ep_ring = virt_dev->eps[ep_index].new_ring; ep_ctx->deq = ep_ring->first_seg->dma | ep_ring->cycle_state; ep_ctx->ep_info = xhci_get_endpoint_interval(udev, ep); /* FIXME dig Mult and streams info out of ep companion desc */ /* Allow 3 retries for everything but isoc; * error count = 0 means infinite retries. */ if (!usb_endpoint_xfer_isoc(&ep->desc)) ep_ctx->ep_info2 = ERROR_COUNT(3); else ep_ctx->ep_info2 = ERROR_COUNT(1); ep_ctx->ep_info2 |= xhci_get_endpoint_type(udev, ep); /* Set the max packet size and max burst */ switch (udev->speed) { case USB_SPEED_SUPER: max_packet = ep->desc.wMaxPacketSize; ep_ctx->ep_info2 |= MAX_PACKET(max_packet); /* dig out max burst from ep companion desc */ if (!ep->ss_ep_comp) { xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n"); max_packet = 0; } else { max_packet = ep->ss_ep_comp->desc.bMaxBurst; } ep_ctx->ep_info2 |= MAX_BURST(max_packet); break; case USB_SPEED_HIGH: /* 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 = (ep->desc.wMaxPacketSize & 0x1800) >> 11; ep_ctx->ep_info2 |= MAX_BURST(max_burst); } /* Fall through */ case USB_SPEED_FULL: case USB_SPEED_LOW: max_packet = ep->desc.wMaxPacketSize & 0x3ff; ep_ctx->ep_info2 |= MAX_PACKET(max_packet); break; default: BUG(); }
int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; 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; int ret = 0; ret = xhci_check_args(hcd, udev, ep, 1, __func__); if (ret <= 0) { ep->hcpriv = NULL; return ret; } xhci = hcd_to_xhci(hcd); added_ctxs = xhci_get_endpoint_flag(&ep->desc); last_ctx = xhci_last_valid_endpoint(added_ctxs); if (added_ctxs == SLOT_FLAG || added_ctxs == EP0_FLAG) { xhci_dbg(xhci, "xHCI %s - can't add slot or ep 0 %#x\n", __func__, added_ctxs); return 0; } if (!xhci->devs || !xhci->devs[udev->slot_id]) { xhci_warn(xhci, "xHCI %s called with unaddressed device\n", __func__); return -EINVAL; } 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_get_ep_ctx(xhci, out_ctx, ep_index); 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; } if (xhci_endpoint_init(xhci, xhci->devs[udev->slot_id], udev, ep, GFP_KERNEL) < 0) { dev_dbg(&udev->dev, "%s - could not initialize ep %#x\n", __func__, ep->desc.bEndpointAddress); return -ENOMEM; } ctrl_ctx->add_flags |= added_ctxs; new_add_flags = ctrl_ctx->add_flags; new_drop_flags = ctrl_ctx->drop_flags; slot_ctx = xhci_get_slot_ctx(xhci, in_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 = slot_ctx->dev_info; ep->hcpriv = udev; xhci_dbg(xhci, "add ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", (unsigned int) ep->desc.bEndpointAddress, udev->slot_id, (unsigned int) new_drop_flags, (unsigned int) new_add_flags, (unsigned int) new_slot_info); return 0; }
int xhci_drop_endpoint(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; 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; u32 drop_flag; u32 new_add_flags, new_drop_flags, new_slot_info; int ret; ret = xhci_check_args(hcd, udev, ep, 1, __func__); if (ret <= 0) return ret; xhci = hcd_to_xhci(hcd); xhci_dbg(xhci, "%s called for udev %p\n", __func__, udev); drop_flag = xhci_get_endpoint_flag(&ep->desc); if (drop_flag == SLOT_FLAG || drop_flag == EP0_FLAG) { xhci_dbg(xhci, "xHCI %s - can't drop slot or ep 0 %#x\n", __func__, drop_flag); return 0; } if (!xhci->devs || !xhci->devs[udev->slot_id]) { xhci_warn(xhci, "xHCI %s called with unaddressed device\n", __func__); return -EINVAL; } 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_get_ep_ctx(xhci, out_ctx, ep_index); if ((ep_ctx->ep_info & EP_STATE_MASK) == EP_STATE_DISABLED || 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; } ctrl_ctx->drop_flags |= drop_flag; new_drop_flags = ctrl_ctx->drop_flags; ctrl_ctx->add_flags &= ~drop_flag; new_add_flags = ctrl_ctx->add_flags; last_ctx = xhci_last_valid_endpoint(ctrl_ctx->add_flags); slot_ctx = xhci_get_slot_ctx(xhci, in_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 = slot_ctx->dev_info; xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x, new slot info = %#x\n", (unsigned int) ep->desc.bEndpointAddress, udev->slot_id, (unsigned int) new_drop_flags, (unsigned int) new_add_flags, (unsigned int) new_slot_info); return 0; }