Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 165046
b: refs/heads/master
c: 63a0d9a
h: refs/heads/master
v: v3
  • Loading branch information
Sarah Sharp authored and Greg Kroah-Hartman committed Sep 23, 2009
1 parent f2daa78 commit fe09169
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 101 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e221be815cd263480928248bfd4541497017a1b
refs/heads/master: 63a0d9abd18cdcf5a985029c266c6bfe0511768f
59 changes: 31 additions & 28 deletions trunk/drivers/usb/host/xhci-hcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,13 +351,14 @@ void xhci_event_ring_work(unsigned long arg)
xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
xhci_dbg_cmd_ptrs(xhci);
for (i = 0; i < MAX_HC_SLOTS; ++i) {
if (xhci->devs[i]) {
for (j = 0; j < 31; ++j) {
if (xhci->devs[i]->ep_rings[j]) {
xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
xhci_debug_segment(xhci, xhci->devs[i]->ep_rings[j]->deq_seg);
}
}
if (!xhci->devs[i])
continue;
for (j = 0; j < 31; ++j) {
struct xhci_ring *ring = xhci->devs[i]->eps[j].ring;
if (!ring)
continue;
xhci_dbg(xhci, "Dev %d endpoint ring %d:\n", i, j);
xhci_debug_segment(xhci, ring->deq_seg);
}
}

Expand Down Expand Up @@ -778,6 +779,7 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
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);
Expand All @@ -790,17 +792,18 @@ int xhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
xhci_dbg(xhci, "Event ring:\n");
xhci_debug_ring(xhci, xhci->event_ring);
ep_index = xhci_get_endpoint_index(&urb->ep->desc);
ep_ring = xhci->devs[urb->dev->slot_id]->ep_rings[ep_index];
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_ring->cancels_pending++;
list_add_tail(&td->cancelled_td_list, &ep_ring->cancelled_td_list);
ep->cancels_pending++;
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_ring->cancels_pending == 1) {
if (ep->cancels_pending == 1) {
xhci_queue_stop_endpoint(xhci, urb->dev->slot_id, ep_index);
xhci_ring_cmd_db(xhci);
}
Expand Down Expand Up @@ -1206,10 +1209,10 @@ int xhci_check_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
xhci_zero_in_ctx(xhci, virt_dev);
/* Free any old rings */
for (i = 1; i < 31; ++i) {
if (virt_dev->new_ep_rings[i]) {
xhci_ring_free(xhci, virt_dev->ep_rings[i]);
virt_dev->ep_rings[i] = virt_dev->new_ep_rings[i];
virt_dev->new_ep_rings[i] = NULL;
if (virt_dev->eps[i].new_ring) {
xhci_ring_free(xhci, virt_dev->eps[i].ring);
virt_dev->eps[i].ring = virt_dev->eps[i].new_ring;
virt_dev->eps[i].new_ring = NULL;
}
}

Expand All @@ -1236,9 +1239,9 @@ void xhci_reset_bandwidth(struct usb_hcd *hcd, struct usb_device *udev)
virt_dev = xhci->devs[udev->slot_id];
/* Free any rings allocated for added endpoints */
for (i = 0; i < 31; ++i) {
if (virt_dev->new_ep_rings[i]) {
xhci_ring_free(xhci, virt_dev->new_ep_rings[i]);
virt_dev->new_ep_rings[i] = NULL;
if (virt_dev->eps[i].new_ring) {
xhci_ring_free(xhci, virt_dev->eps[i].new_ring);
virt_dev->eps[i].new_ring = NULL;
}
}
xhci_zero_in_ctx(xhci, virt_dev);
Expand Down Expand Up @@ -1281,26 +1284,26 @@ void xhci_setup_input_ctx_for_quirk(struct xhci_hcd *xhci,
}

void xhci_cleanup_stalled_ring(struct xhci_hcd *xhci,
struct usb_device *udev,
unsigned int ep_index, struct xhci_ring *ep_ring)
struct usb_device *udev, unsigned int ep_index)
{
struct xhci_dequeue_state deq_state;
struct xhci_virt_ep *ep;

xhci_dbg(xhci, "Cleaning up stalled endpoint ring\n");
ep = &xhci->devs[udev->slot_id]->eps[ep_index];
/* We need to move the HW's dequeue pointer past this TD,
* or it will attempt to resend it on the next doorbell ring.
*/
xhci_find_new_dequeue_state(xhci, udev->slot_id,
ep_index, ep_ring->stopped_td,
ep_index, ep->stopped_td,
&deq_state);

/* HW with the reset endpoint quirk will use the saved dequeue state to
* issue a configure endpoint command later.
*/
if (!(xhci->quirks & XHCI_RESET_EP_QUIRK)) {
xhci_dbg(xhci, "Queueing new dequeue state\n");
xhci_queue_new_dequeue_state(xhci, ep_ring,
udev->slot_id,
xhci_queue_new_dequeue_state(xhci, udev->slot_id,
ep_index, &deq_state);
} else {
/* Better hope no one uses the input context between now and the
Expand All @@ -1327,7 +1330,7 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
unsigned int ep_index;
unsigned long flags;
int ret;
struct xhci_ring *ep_ring;
struct xhci_virt_ep *virt_ep;

xhci = hcd_to_xhci(hcd);
udev = (struct usb_device *) ep->hcpriv;
Expand All @@ -1337,8 +1340,8 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
if (!ep->hcpriv)
return;
ep_index = xhci_get_endpoint_index(&ep->desc);
ep_ring = xhci->devs[udev->slot_id]->ep_rings[ep_index];
if (!ep_ring->stopped_td) {
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;
Expand All @@ -1357,8 +1360,8 @@ void xhci_endpoint_reset(struct usb_hcd *hcd,
* command. Better hope that last command worked!
*/
if (!ret) {
xhci_cleanup_stalled_ring(xhci, udev, ep_index, ep_ring);
kfree(ep_ring->stopped_td);
xhci_cleanup_stalled_ring(xhci, udev, ep_index);
kfree(virt_ep->stopped_td);
xhci_ring_cmd_db(xhci);
}
spin_unlock_irqrestore(&xhci->lock, flags);
Expand Down
25 changes: 15 additions & 10 deletions trunk/drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ static struct xhci_ring *xhci_ring_alloc(struct xhci_hcd *xhci,
return 0;

INIT_LIST_HEAD(&ring->td_list);
INIT_LIST_HEAD(&ring->cancelled_td_list);
if (num_segs == 0)
return ring;

Expand Down Expand Up @@ -265,8 +264,8 @@ void xhci_free_virt_device(struct xhci_hcd *xhci, int slot_id)
return;

for (i = 0; i < 31; ++i)
if (dev->ep_rings[i])
xhci_ring_free(xhci, dev->ep_rings[i]);
if (dev->eps[i].ring)
xhci_ring_free(xhci, dev->eps[i].ring);

if (dev->in_ctx)
xhci_free_container_ctx(xhci, dev->in_ctx);
Expand All @@ -281,6 +280,7 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
struct usb_device *udev, gfp_t flags)
{
struct xhci_virt_device *dev;
int i;

/* Slot ID 0 is reserved */
if (slot_id == 0 || xhci->devs[slot_id]) {
Expand Down Expand Up @@ -309,9 +309,13 @@ int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
xhci_dbg(xhci, "Slot %d input ctx = 0x%llx (dma)\n", slot_id,
(unsigned long long)dev->in_ctx->dma);

/* Initialize the cancellation list for each endpoint */
for (i = 0; i < 31; i++)
INIT_LIST_HEAD(&dev->eps[i].cancelled_td_list);

/* Allocate endpoint 0 ring */
dev->ep_rings[0] = xhci_ring_alloc(xhci, 1, true, flags);
if (!dev->ep_rings[0])
dev->eps[0].ring = xhci_ring_alloc(xhci, 1, true, flags);
if (!dev->eps[0].ring)
goto fail;

init_completion(&dev->cmd_completion);
Expand Down Expand Up @@ -428,8 +432,8 @@ int xhci_setup_addressable_virt_dev(struct xhci_hcd *xhci, struct usb_device *ud
ep0_ctx->ep_info2 |= ERROR_COUNT(3);

ep0_ctx->deq =
dev->ep_rings[0]->first_seg->dma;
ep0_ctx->deq |= dev->ep_rings[0]->cycle_state;
dev->eps[0].ring->first_seg->dma;
ep0_ctx->deq |= dev->eps[0].ring->cycle_state;

/* Steps 7 and 8 were done in xhci_alloc_virt_device() */

Expand Down Expand Up @@ -539,10 +543,11 @@ int xhci_endpoint_init(struct xhci_hcd *xhci,
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);
if (!virt_dev->new_ep_rings[ep_index])
virt_dev->eps[ep_index].new_ring =
xhci_ring_alloc(xhci, 1, true, mem_flags);
if (!virt_dev->eps[ep_index].new_ring)
return -ENOMEM;
ep_ring = virt_dev->new_ep_rings[ep_index];
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);
Expand Down
Loading

0 comments on commit fe09169

Please sign in to comment.