aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-07-22 18:23:08 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:41 -0400
commit22405ed2e1bd8d2676cb45c578bdd05527ce25b9 (patch)
tree50fc29c7f4957cccdcd2ed02b8ecd43fc17b0f76 /drivers/usb/host
parent8af56be185a94e39c80ce90fc9f83f3058a3ce80 (diff)
USB xHCI: handle_tx_event() refactor: process_bulk_intr_td
This patch moves the bulk and interrupt td processing part in handle_tx_event() into a separate function process_bulk_intr_td(). Signed-off-by: Andiry Xu <andiry.xu@amd.com> Signed-off-by: Sarah Sharp <sarah.a.sharp@linux.intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host')
-rw-r--r--drivers/usb/host/xhci-ring.c216
1 files changed, 115 insertions, 101 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index e28cfd15e1a6..83580cf794d1 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1459,6 +1459,117 @@ static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
1459} 1459}
1460 1460
1461/* 1461/*
1462 * Process bulk and interrupt tds, update urb status and actual_length.
1463 */
1464static int process_bulk_intr_td(struct xhci_hcd *xhci, struct xhci_td *td,
1465 union xhci_trb *event_trb, struct xhci_transfer_event *event,
1466 struct xhci_virt_ep *ep, int *status)
1467{
1468 struct xhci_ring *ep_ring;
1469 union xhci_trb *cur_trb;
1470 struct xhci_segment *cur_seg;
1471 u32 trb_comp_code;
1472
1473 ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer);
1474 trb_comp_code = GET_COMP_CODE(event->transfer_len);
1475
1476 switch (trb_comp_code) {
1477 case COMP_SUCCESS:
1478 /* Double check that the HW transferred everything. */
1479 if (event_trb != td->last_trb) {
1480 xhci_warn(xhci, "WARN Successful completion "
1481 "on short TX\n");
1482 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1483 *status = -EREMOTEIO;
1484 else
1485 *status = 0;
1486 } else {
1487 if (usb_endpoint_xfer_bulk(&td->urb->ep->desc))
1488 xhci_dbg(xhci, "Successful bulk "
1489 "transfer!\n");
1490 else
1491 xhci_dbg(xhci, "Successful interrupt "
1492 "transfer!\n");
1493 *status = 0;
1494 }
1495 break;
1496 case COMP_SHORT_TX:
1497 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1498 *status = -EREMOTEIO;
1499 else
1500 *status = 0;
1501 break;
1502 default:
1503 /* Others already handled above */
1504 break;
1505 }
1506 dev_dbg(&td->urb->dev->dev,
1507 "ep %#x - asked for %d bytes, "
1508 "%d bytes untransferred\n",
1509 td->urb->ep->desc.bEndpointAddress,
1510 td->urb->transfer_buffer_length,
1511 TRB_LEN(event->transfer_len));
1512 /* Fast path - was this the last TRB in the TD for this URB? */
1513 if (event_trb == td->last_trb) {
1514 if (TRB_LEN(event->transfer_len) != 0) {
1515 td->urb->actual_length =
1516 td->urb->transfer_buffer_length -
1517 TRB_LEN(event->transfer_len);
1518 if (td->urb->transfer_buffer_length <
1519 td->urb->actual_length) {
1520 xhci_warn(xhci, "HC gave bad length "
1521 "of %d bytes left\n",
1522 TRB_LEN(event->transfer_len));
1523 td->urb->actual_length = 0;
1524 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1525 *status = -EREMOTEIO;
1526 else
1527 *status = 0;
1528 }
1529 /* Don't overwrite a previously set error code */
1530 if (*status == -EINPROGRESS) {
1531 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1532 *status = -EREMOTEIO;
1533 else
1534 *status = 0;
1535 }
1536 } else {
1537 td->urb->actual_length =
1538 td->urb->transfer_buffer_length;
1539 /* Ignore a short packet completion if the
1540 * untransferred length was zero.
1541 */
1542 if (*status == -EREMOTEIO)
1543 *status = 0;
1544 }
1545 } else {
1546 /* Slow path - walk the list, starting from the dequeue
1547 * pointer, to get the actual length transferred.
1548 */
1549 td->urb->actual_length = 0;
1550 for (cur_trb = ep_ring->dequeue, cur_seg = ep_ring->deq_seg;
1551 cur_trb != event_trb;
1552 next_trb(xhci, ep_ring, &cur_seg, &cur_trb)) {
1553 if ((cur_trb->generic.field[3] &
1554 TRB_TYPE_BITMASK) != TRB_TYPE(TRB_TR_NOOP) &&
1555 (cur_trb->generic.field[3] &
1556 TRB_TYPE_BITMASK) != TRB_TYPE(TRB_LINK))
1557 td->urb->actual_length +=
1558 TRB_LEN(cur_trb->generic.field[2]);
1559 }
1560 /* If the ring didn't stop on a Link or No-op TRB, add
1561 * in the actual bytes transferred from the Normal TRB
1562 */
1563 if (trb_comp_code != COMP_STOP_INVAL)
1564 td->urb->actual_length +=
1565 TRB_LEN(cur_trb->generic.field[2]) -
1566 TRB_LEN(event->transfer_len);
1567 }
1568
1569 return finish_td(xhci, td, event_trb, event, ep, status, false);
1570}
1571
1572/*
1462 * If this function returns an error condition, it means it got a Transfer 1573 * If this function returns an error condition, it means it got a Transfer
1463 * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. 1574 * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
1464 * At this point, the host controller is probably hosed and should be reset. 1575 * At this point, the host controller is probably hosed and should be reset.
@@ -1584,109 +1695,12 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1584 } 1695 }
1585 /* Now update the urb's actual_length and give back to the core */ 1696 /* Now update the urb's actual_length and give back to the core */
1586 /* Was this a control transfer? */ 1697 /* Was this a control transfer? */
1587 if (usb_endpoint_xfer_control(&td->urb->ep->desc)) { 1698 if (usb_endpoint_xfer_control(&td->urb->ep->desc))
1588 ret = process_ctrl_td(xhci, td, event_trb, event, ep, 1699 ret = process_ctrl_td(xhci, td, event_trb, event, ep,
1589 &status); 1700 &status);
1590 goto cleanup; 1701 else
1591 } else { 1702 ret = process_bulk_intr_td(xhci, td, event_trb, event, ep,
1592 switch (trb_comp_code) { 1703 &status);
1593 case COMP_SUCCESS:
1594 /* Double check that the HW transferred everything. */
1595 if (event_trb != td->last_trb) {
1596 xhci_warn(xhci, "WARN Successful completion "
1597 "on short TX\n");
1598 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1599 status = -EREMOTEIO;
1600 else
1601 status = 0;
1602 } else {
1603 if (usb_endpoint_xfer_bulk(&td->urb->ep->desc))
1604 xhci_dbg(xhci, "Successful bulk "
1605 "transfer!\n");
1606 else
1607 xhci_dbg(xhci, "Successful interrupt "
1608 "transfer!\n");
1609 status = 0;
1610 }
1611 break;
1612 case COMP_SHORT_TX:
1613 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1614 status = -EREMOTEIO;
1615 else
1616 status = 0;
1617 break;
1618 default:
1619 /* Others already handled above */
1620 break;
1621 }
1622 dev_dbg(&td->urb->dev->dev,
1623 "ep %#x - asked for %d bytes, "
1624 "%d bytes untransferred\n",
1625 td->urb->ep->desc.bEndpointAddress,
1626 td->urb->transfer_buffer_length,
1627 TRB_LEN(event->transfer_len));
1628 /* Fast path - was this the last TRB in the TD for this URB? */
1629 if (event_trb == td->last_trb) {
1630 if (TRB_LEN(event->transfer_len) != 0) {
1631 td->urb->actual_length =
1632 td->urb->transfer_buffer_length -
1633 TRB_LEN(event->transfer_len);
1634 if (td->urb->transfer_buffer_length <
1635 td->urb->actual_length) {
1636 xhci_warn(xhci, "HC gave bad length "
1637 "of %d bytes left\n",
1638 TRB_LEN(event->transfer_len));
1639 td->urb->actual_length = 0;
1640 if (td->urb->transfer_flags &
1641 URB_SHORT_NOT_OK)
1642 status = -EREMOTEIO;
1643 else
1644 status = 0;
1645 }
1646 /* Don't overwrite a previously set error code */
1647 if (status == -EINPROGRESS) {
1648 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1649 status = -EREMOTEIO;
1650 else
1651 status = 0;
1652 }
1653 } else {
1654 td->urb->actual_length = td->urb->transfer_buffer_length;
1655 /* Ignore a short packet completion if the
1656 * untransferred length was zero.
1657 */
1658 if (status == -EREMOTEIO)
1659 status = 0;
1660 }
1661 } else {
1662 /* Slow path - walk the list, starting from the dequeue
1663 * pointer, to get the actual length transferred.
1664 */
1665 union xhci_trb *cur_trb;
1666 struct xhci_segment *cur_seg;
1667
1668 td->urb->actual_length = 0;
1669 for (cur_trb = ep_ring->dequeue, cur_seg = ep_ring->deq_seg;
1670 cur_trb != event_trb;
1671 next_trb(xhci, ep_ring, &cur_seg, &cur_trb)) {
1672 if ((cur_trb->generic.field[3] &
1673 TRB_TYPE_BITMASK) != TRB_TYPE(TRB_TR_NOOP) &&
1674 (cur_trb->generic.field[3] &
1675 TRB_TYPE_BITMASK) != TRB_TYPE(TRB_LINK))
1676 td->urb->actual_length +=
1677 TRB_LEN(cur_trb->generic.field[2]);
1678 }
1679 /* If the ring didn't stop on a Link or No-op TRB, add
1680 * in the actual bytes transferred from the Normal TRB
1681 */
1682 if (trb_comp_code != COMP_STOP_INVAL)
1683 td->urb->actual_length +=
1684 TRB_LEN(cur_trb->generic.field[2]) -
1685 TRB_LEN(event->transfer_len);
1686 }
1687 }
1688
1689 ret = finish_td(xhci, td, event_trb, event, ep, &status, false);
1690 1704
1691cleanup: 1705cleanup:
1692 inc_deq(xhci, xhci->event_ring, true); 1706 inc_deq(xhci, xhci->event_ring, true);