aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host
diff options
context:
space:
mode:
authorAndiry Xu <andiry.xu@amd.com>2010-07-22 18:23:03 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-08-10 17:35:41 -0400
commit8af56be185a94e39c80ce90fc9f83f3058a3ce80 (patch)
tree9904122b745b067b10ce067d689ff52d9f3105d9 /drivers/usb/host
parent4422da61550b2fe5089c5cdc374ceea33e581773 (diff)
USB: xHCI: handle_tx_event() refactor: process_ctrl_td
This patch moves the ctrl td processing part in handle_tx_event() into a separate function process_ctrl_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.c184
1 files changed, 106 insertions, 78 deletions
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index 691a108295ea..e28cfd15e1a6 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1356,6 +1356,109 @@ td_cleanup:
1356} 1356}
1357 1357
1358/* 1358/*
1359 * Process control tds, update urb status and actual_length.
1360 */
1361static int process_ctrl_td(struct xhci_hcd *xhci, struct xhci_td *td,
1362 union xhci_trb *event_trb, struct xhci_transfer_event *event,
1363 struct xhci_virt_ep *ep, int *status)
1364{
1365 struct xhci_virt_device *xdev;
1366 struct xhci_ring *ep_ring;
1367 unsigned int slot_id;
1368 int ep_index;
1369 struct xhci_ep_ctx *ep_ctx;
1370 u32 trb_comp_code;
1371
1372 slot_id = TRB_TO_SLOT_ID(event->flags);
1373 xdev = xhci->devs[slot_id];
1374 ep_index = TRB_TO_EP_ID(event->flags) - 1;
1375 ep_ring = xhci_dma_to_transfer_ring(ep, event->buffer);
1376 ep_ctx = xhci_get_ep_ctx(xhci, xdev->out_ctx, ep_index);
1377 trb_comp_code = GET_COMP_CODE(event->transfer_len);
1378
1379 xhci_debug_trb(xhci, xhci->event_ring->dequeue);
1380 switch (trb_comp_code) {
1381 case COMP_SUCCESS:
1382 if (event_trb == ep_ring->dequeue) {
1383 xhci_warn(xhci, "WARN: Success on ctrl setup TRB "
1384 "without IOC set??\n");
1385 *status = -ESHUTDOWN;
1386 } else if (event_trb != td->last_trb) {
1387 xhci_warn(xhci, "WARN: Success on ctrl data TRB "
1388 "without IOC set??\n");
1389 *status = -ESHUTDOWN;
1390 } else {
1391 xhci_dbg(xhci, "Successful control transfer!\n");
1392 *status = 0;
1393 }
1394 break;
1395 case COMP_SHORT_TX:
1396 xhci_warn(xhci, "WARN: short transfer on control ep\n");
1397 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1398 *status = -EREMOTEIO;
1399 else
1400 *status = 0;
1401 break;
1402 default:
1403 if (!xhci_requires_manual_halt_cleanup(xhci,
1404 ep_ctx, trb_comp_code))
1405 break;
1406 xhci_dbg(xhci, "TRB error code %u, "
1407 "halted endpoint index = %u\n",
1408 trb_comp_code, ep_index);
1409 /* else fall through */
1410 case COMP_STALL:
1411 /* Did we transfer part of the data (middle) phase? */
1412 if (event_trb != ep_ring->dequeue &&
1413 event_trb != td->last_trb)
1414 td->urb->actual_length =
1415 td->urb->transfer_buffer_length
1416 - TRB_LEN(event->transfer_len);
1417 else
1418 td->urb->actual_length = 0;
1419
1420 xhci_cleanup_halted_endpoint(xhci,
1421 slot_id, ep_index, 0, td, event_trb);
1422 return finish_td(xhci, td, event_trb, event, ep, status, true);
1423 }
1424 /*
1425 * Did we transfer any data, despite the errors that might have
1426 * happened? I.e. did we get past the setup stage?
1427 */
1428 if (event_trb != ep_ring->dequeue) {
1429 /* The event was for the status stage */
1430 if (event_trb == td->last_trb) {
1431 if (td->urb->actual_length != 0) {
1432 /* Don't overwrite a previously set error code
1433 */
1434 if ((*status == -EINPROGRESS || *status == 0) &&
1435 (td->urb->transfer_flags
1436 & URB_SHORT_NOT_OK))
1437 /* Did we already see a short data
1438 * stage? */
1439 *status = -EREMOTEIO;
1440 } else {
1441 td->urb->actual_length =
1442 td->urb->transfer_buffer_length;
1443 }
1444 } else {
1445 /* Maybe the event was for the data stage? */
1446 if (trb_comp_code != COMP_STOP_INVAL) {
1447 /* We didn't stop on a link TRB in the middle */
1448 td->urb->actual_length =
1449 td->urb->transfer_buffer_length -
1450 TRB_LEN(event->transfer_len);
1451 xhci_dbg(xhci, "Waiting for status "
1452 "stage event\n");
1453 return 0;
1454 }
1455 }
1456 }
1457
1458 return finish_td(xhci, td, event_trb, event, ep, status, false);
1459}
1460
1461/*
1359 * If this function returns an error condition, it means it got a Transfer 1462 * If this function returns an error condition, it means it got a Transfer
1360 * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address. 1463 * event with a corrupted Slot ID, Endpoint ID, or TRB DMA address.
1361 * At this point, the host controller is probably hosed and should be reset. 1464 * At this point, the host controller is probably hosed and should be reset.
@@ -1482,84 +1585,9 @@ static int handle_tx_event(struct xhci_hcd *xhci,
1482 /* Now update the urb's actual_length and give back to the core */ 1585 /* Now update the urb's actual_length and give back to the core */
1483 /* Was this a control transfer? */ 1586 /* Was this a control transfer? */
1484 if (usb_endpoint_xfer_control(&td->urb->ep->desc)) { 1587 if (usb_endpoint_xfer_control(&td->urb->ep->desc)) {
1485 xhci_debug_trb(xhci, xhci->event_ring->dequeue); 1588 ret = process_ctrl_td(xhci, td, event_trb, event, ep,
1486 switch (trb_comp_code) { 1589 &status);
1487 case COMP_SUCCESS: 1590 goto cleanup;
1488 if (event_trb == ep_ring->dequeue) {
1489 xhci_warn(xhci, "WARN: Success on ctrl setup TRB without IOC set??\n");
1490 status = -ESHUTDOWN;
1491 } else if (event_trb != td->last_trb) {
1492 xhci_warn(xhci, "WARN: Success on ctrl data TRB without IOC set??\n");
1493 status = -ESHUTDOWN;
1494 } else {
1495 xhci_dbg(xhci, "Successful control transfer!\n");
1496 status = 0;
1497 }
1498 break;
1499 case COMP_SHORT_TX:
1500 xhci_warn(xhci, "WARN: short transfer on control ep\n");
1501 if (td->urb->transfer_flags & URB_SHORT_NOT_OK)
1502 status = -EREMOTEIO;
1503 else
1504 status = 0;
1505 break;
1506
1507 default:
1508 if (!xhci_requires_manual_halt_cleanup(xhci,
1509 ep_ctx, trb_comp_code))
1510 break;
1511 xhci_dbg(xhci, "TRB error code %u, "
1512 "halted endpoint index = %u\n",
1513 trb_comp_code, ep_index);
1514 /* else fall through */
1515 case COMP_STALL:
1516 /* Did we transfer part of the data (middle) phase? */
1517 if (event_trb != ep_ring->dequeue &&
1518 event_trb != td->last_trb)
1519 td->urb->actual_length =
1520 td->urb->transfer_buffer_length
1521 - TRB_LEN(event->transfer_len);
1522 else
1523 td->urb->actual_length = 0;
1524
1525 xhci_cleanup_halted_endpoint(xhci,
1526 slot_id, ep_index, 0, td, event_trb);
1527
1528 ret = finish_td(xhci, td, event_trb, event, ep,
1529 &status, true);
1530 goto cleanup;
1531 }
1532 /*
1533 * Did we transfer any data, despite the errors that might have
1534 * happened? I.e. did we get past the setup stage?
1535 */
1536 if (event_trb != ep_ring->dequeue) {
1537 /* The event was for the status stage */
1538 if (event_trb == td->last_trb) {
1539 if (td->urb->actual_length != 0) {
1540 /* Don't overwrite a previously set error code */
1541 if ((status == -EINPROGRESS ||
1542 status == 0) &&
1543 (td->urb->transfer_flags
1544 & URB_SHORT_NOT_OK))
1545 /* Did we already see a short data stage? */
1546 status = -EREMOTEIO;
1547 } else {
1548 td->urb->actual_length =
1549 td->urb->transfer_buffer_length;
1550 }
1551 } else {
1552 /* Maybe the event was for the data stage? */
1553 if (trb_comp_code != COMP_STOP_INVAL) {
1554 /* We didn't stop on a link TRB in the middle */
1555 td->urb->actual_length =
1556 td->urb->transfer_buffer_length -
1557 TRB_LEN(event->transfer_len);
1558 xhci_dbg(xhci, "Waiting for status stage event\n");
1559 goto cleanup;
1560 }
1561 }
1562 }
1563 } else { 1591 } else {
1564 switch (trb_comp_code) { 1592 switch (trb_comp_code) {
1565 case COMP_SUCCESS: 1593 case COMP_SUCCESS: