/* * queue push/pop */ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) { struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); struct urb *urb = ureq->urb; struct device *dev = usbhs_priv_to_dev(priv); int status = 0; dev_dbg(dev, "%s\n", __func__); if (!urb) { dev_warn(dev, "pkt doesn't have urb\n"); return; } if (!usbhsh_is_running(hpriv)) status = -ESHUTDOWN; urb->actual_length = pkt->actual; usbhsh_endpoint_sequence_save(hpriv, urb, pkt); usbhsh_ureq_free(hpriv, ureq); usbhsh_pipe_detach(hpriv, usbhsh_ep_to_uep(urb->ep)); usb_hcd_unlink_urb_from_ep(hcd, urb); usb_hcd_giveback_urb(hcd, urb, status); }
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; }
/* * 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; }
/* * queue up an urb for anything except the root hub */ static int admhc_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { struct admhcd *ahcd = hcd_to_admhcd(hcd); struct ed *ed; struct urb_priv *urb_priv; unsigned int pipe = urb->pipe; int td_cnt = 0; unsigned long flags; int ret = 0; #ifdef ADMHC_VERBOSE_DEBUG spin_lock_irqsave(&ahcd->lock, flags); urb_print(ahcd, urb, "ENQEUE", usb_pipein(pipe), -EINPROGRESS); spin_unlock_irqrestore(&ahcd->lock, flags); #endif /* every endpoint has an ed, locate and maybe (re)initialize it */ ed = ed_get(ahcd, urb->ep, urb->dev, pipe, urb->interval); if (!ed) return -ENOMEM; /* for the private part of the URB we need the number of TDs */ switch (ed->type) { case PIPE_CONTROL: if (urb->transfer_buffer_length > TD_DATALEN_MAX) /* td_submit_urb() doesn't yet handle these */ return -EMSGSIZE; /* 1 TD for setup, 1 for ACK, plus ... */ td_cnt = 2; /* FALLTHROUGH */ case PIPE_BULK: /* one TD for every 4096 Bytes (can be upto 8K) */ td_cnt += urb->transfer_buffer_length / TD_DATALEN_MAX; /* ... and for any remaining bytes ... */ if ((urb->transfer_buffer_length % TD_DATALEN_MAX) != 0) td_cnt++; /* ... and maybe a zero length packet to wrap it up */ if (td_cnt == 0) td_cnt++; else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 && (urb->transfer_buffer_length % usb_maxpacket(urb->dev, pipe, usb_pipeout (pipe))) == 0) td_cnt++; break; case PIPE_INTERRUPT: /* * for Interrupt IN/OUT transactions, each ED contains * only 1 TD. * TODO: check transfer_buffer_length? */ td_cnt = 1; break; case PIPE_ISOCHRONOUS: /* number of packets from URB */ td_cnt = urb->number_of_packets; break; } urb_priv = urb_priv_alloc(ahcd, td_cnt, mem_flags); if (!urb_priv) return -ENOMEM; urb_priv->ed = ed; spin_lock_irqsave(&ahcd->lock, flags); /* don't submit to a dead HC */ if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { ret = -ENODEV; goto fail; } if (!HC_IS_RUNNING(hcd->state)) { ret = -ENODEV; goto fail; } ret = usb_hcd_link_urb_to_ep(hcd, urb); if (ret) goto fail; /* schedule the ed if needed */ if (ed->state == ED_IDLE) { ret = ed_schedule(ahcd, ed); if (ret < 0) { usb_hcd_unlink_urb_from_ep(hcd, urb); goto fail; } if (ed->type == PIPE_ISOCHRONOUS) { u16 frame = admhc_frame_no(ahcd); /* delay a few frames before the first TD */ frame += max_t (u16, 8, ed->interval); frame &= ~(ed->interval - 1); frame |= ed->branch; urb->start_frame = frame; /* yes, only URB_ISO_ASAP is supported, and * urb->start_frame is never used as input. */ } } else if (ed->type == PIPE_ISOCHRONOUS) urb->start_frame = ed->last_iso + ed->interval; /* fill the TDs and link them to the ed; and * enable that part of the schedule, if needed * and update count of queued periodic urbs */ urb->hcpriv = urb_priv; td_submit_urb(ahcd, urb); #ifdef ADMHC_VERBOSE_DEBUG admhc_dump_ed(ahcd, "admhc_urb_enqueue", urb_priv->ed, 1); #endif fail: if (ret) urb_priv_free(ahcd, urb_priv); spin_unlock_irqrestore(&ahcd->lock, flags); return ret; }