aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-q.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/host/uhci-q.c')
-rw-r--r--drivers/usb/host/uhci-q.c70
1 files changed, 26 insertions, 44 deletions
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index 3bb908ca38e9..e5d60d5b105a 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -757,7 +757,6 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci,
757 uhci_free_td(uhci, td); 757 uhci_free_td(uhci, td);
758 } 758 }
759 759
760 urbp->urb->hcpriv = NULL;
761 kmem_cache_free(uhci_up_cachep, urbp); 760 kmem_cache_free(uhci_up_cachep, urbp);
762} 761}
763 762
@@ -1324,7 +1323,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
1324 if (list_empty(&qh->queue)) { 1323 if (list_empty(&qh->queue)) {
1325 qh->iso_packet_desc = &urb->iso_frame_desc[0]; 1324 qh->iso_packet_desc = &urb->iso_frame_desc[0];
1326 qh->iso_frame = urb->start_frame; 1325 qh->iso_frame = urb->start_frame;
1327 qh->iso_status = 0;
1328 } 1326 }
1329 1327
1330 qh->skel = SKEL_ISO; 1328 qh->skel = SKEL_ISO;
@@ -1361,22 +1359,18 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb)
1361 qh->iso_packet_desc->actual_length = actlength; 1359 qh->iso_packet_desc->actual_length = actlength;
1362 qh->iso_packet_desc->status = status; 1360 qh->iso_packet_desc->status = status;
1363 } 1361 }
1364 1362 if (status)
1365 if (status) {
1366 urb->error_count++; 1363 urb->error_count++;
1367 qh->iso_status = status;
1368 }
1369 1364
1370 uhci_remove_td_from_urbp(td); 1365 uhci_remove_td_from_urbp(td);
1371 uhci_free_td(uhci, td); 1366 uhci_free_td(uhci, td);
1372 qh->iso_frame += qh->period; 1367 qh->iso_frame += qh->period;
1373 ++qh->iso_packet_desc; 1368 ++qh->iso_packet_desc;
1374 } 1369 }
1375 return qh->iso_status; 1370 return 0;
1376} 1371}
1377 1372
1378static int uhci_urb_enqueue(struct usb_hcd *hcd, 1373static int uhci_urb_enqueue(struct usb_hcd *hcd,
1379 struct usb_host_endpoint *hep,
1380 struct urb *urb, gfp_t mem_flags) 1374 struct urb *urb, gfp_t mem_flags)
1381{ 1375{
1382 int ret; 1376 int ret;
@@ -1387,19 +1381,19 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1387 1381
1388 spin_lock_irqsave(&uhci->lock, flags); 1382 spin_lock_irqsave(&uhci->lock, flags);
1389 1383
1390 ret = urb->status; 1384 ret = usb_hcd_link_urb_to_ep(hcd, urb);
1391 if (ret != -EINPROGRESS) /* URB already unlinked! */ 1385 if (ret)
1392 goto done; 1386 goto done_not_linked;
1393 1387
1394 ret = -ENOMEM; 1388 ret = -ENOMEM;
1395 urbp = uhci_alloc_urb_priv(uhci, urb); 1389 urbp = uhci_alloc_urb_priv(uhci, urb);
1396 if (!urbp) 1390 if (!urbp)
1397 goto done; 1391 goto done;
1398 1392
1399 if (hep->hcpriv) 1393 if (urb->ep->hcpriv)
1400 qh = (struct uhci_qh *) hep->hcpriv; 1394 qh = urb->ep->hcpriv;
1401 else { 1395 else {
1402 qh = uhci_alloc_qh(uhci, urb->dev, hep); 1396 qh = uhci_alloc_qh(uhci, urb->dev, urb->ep);
1403 if (!qh) 1397 if (!qh)
1404 goto err_no_qh; 1398 goto err_no_qh;
1405 } 1399 }
@@ -1440,27 +1434,29 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd,
1440err_submit_failed: 1434err_submit_failed:
1441 if (qh->state == QH_STATE_IDLE) 1435 if (qh->state == QH_STATE_IDLE)
1442 uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ 1436 uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */
1443
1444err_no_qh: 1437err_no_qh:
1445 uhci_free_urb_priv(uhci, urbp); 1438 uhci_free_urb_priv(uhci, urbp);
1446
1447done: 1439done:
1440 if (ret)
1441 usb_hcd_unlink_urb_from_ep(hcd, urb);
1442done_not_linked:
1448 spin_unlock_irqrestore(&uhci->lock, flags); 1443 spin_unlock_irqrestore(&uhci->lock, flags);
1449 return ret; 1444 return ret;
1450} 1445}
1451 1446
1452static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) 1447static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
1453{ 1448{
1454 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 1449 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
1455 unsigned long flags; 1450 unsigned long flags;
1456 struct urb_priv *urbp;
1457 struct uhci_qh *qh; 1451 struct uhci_qh *qh;
1452 int rc;
1458 1453
1459 spin_lock_irqsave(&uhci->lock, flags); 1454 spin_lock_irqsave(&uhci->lock, flags);
1460 urbp = urb->hcpriv; 1455 rc = usb_hcd_check_unlink_urb(hcd, urb, status);
1461 if (!urbp) /* URB was never linked! */ 1456 if (rc)
1462 goto done; 1457 goto done;
1463 qh = urbp->qh; 1458
1459 qh = ((struct urb_priv *) urb->hcpriv)->qh;
1464 1460
1465 /* Remove Isochronous TDs from the frame list ASAP */ 1461 /* Remove Isochronous TDs from the frame list ASAP */
1466 if (qh->type == USB_ENDPOINT_XFER_ISOC) { 1462 if (qh->type == USB_ENDPOINT_XFER_ISOC) {
@@ -1477,14 +1473,14 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb)
1477 1473
1478done: 1474done:
1479 spin_unlock_irqrestore(&uhci->lock, flags); 1475 spin_unlock_irqrestore(&uhci->lock, flags);
1480 return 0; 1476 return rc;
1481} 1477}
1482 1478
1483/* 1479/*
1484 * Finish unlinking an URB and give it back 1480 * Finish unlinking an URB and give it back
1485 */ 1481 */
1486static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, 1482static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh,
1487 struct urb *urb) 1483 struct urb *urb, int status)
1488__releases(uhci->lock) 1484__releases(uhci->lock)
1489__acquires(uhci->lock) 1485__acquires(uhci->lock)
1490{ 1486{
@@ -1497,13 +1493,6 @@ __acquires(uhci->lock)
1497 * unlinked first. Regardless, don't confuse people with a 1493 * unlinked first. Regardless, don't confuse people with a
1498 * negative length. */ 1494 * negative length. */
1499 urb->actual_length = max(urb->actual_length, 0); 1495 urb->actual_length = max(urb->actual_length, 0);
1500
1501 /* Report erroneous short transfers */
1502 if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
1503 urb->actual_length <
1504 urb->transfer_buffer_length &&
1505 urb->status == 0))
1506 urb->status = -EREMOTEIO;
1507 } 1496 }
1508 1497
1509 /* When giving back the first URB in an Isochronous queue, 1498 /* When giving back the first URB in an Isochronous queue,
@@ -1516,7 +1505,6 @@ __acquires(uhci->lock)
1516 1505
1517 qh->iso_packet_desc = &nurb->iso_frame_desc[0]; 1506 qh->iso_packet_desc = &nurb->iso_frame_desc[0];
1518 qh->iso_frame = nurb->start_frame; 1507 qh->iso_frame = nurb->start_frame;
1519 qh->iso_status = 0;
1520 } 1508 }
1521 1509
1522 /* Take the URB off the QH's queue. If the queue is now empty, 1510 /* Take the URB off the QH's queue. If the queue is now empty,
@@ -1529,9 +1517,10 @@ __acquires(uhci->lock)
1529 } 1517 }
1530 1518
1531 uhci_free_urb_priv(uhci, urbp); 1519 uhci_free_urb_priv(uhci, urbp);
1520 usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb);
1532 1521
1533 spin_unlock(&uhci->lock); 1522 spin_unlock(&uhci->lock);
1534 usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); 1523 usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, status);
1535 spin_lock(&uhci->lock); 1524 spin_lock(&uhci->lock);
1536 1525
1537 /* If the queue is now empty, we can unlink the QH and give up its 1526 /* If the queue is now empty, we can unlink the QH and give up its
@@ -1567,24 +1556,17 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
1567 if (status == -EINPROGRESS) 1556 if (status == -EINPROGRESS)
1568 break; 1557 break;
1569 1558
1570 spin_lock(&urb->lock);
1571 if (urb->status == -EINPROGRESS) /* Not dequeued */
1572 urb->status = status;
1573 else
1574 status = ECONNRESET; /* Not -ECONNRESET */
1575 spin_unlock(&urb->lock);
1576
1577 /* Dequeued but completed URBs can't be given back unless 1559 /* Dequeued but completed URBs can't be given back unless
1578 * the QH is stopped or has finished unlinking. */ 1560 * the QH is stopped or has finished unlinking. */
1579 if (status == ECONNRESET) { 1561 if (urb->unlinked) {
1580 if (QH_FINISHED_UNLINKING(qh)) 1562 if (QH_FINISHED_UNLINKING(qh))
1581 qh->is_stopped = 1; 1563 qh->is_stopped = 1;
1582 else if (!qh->is_stopped) 1564 else if (!qh->is_stopped)
1583 return; 1565 return;
1584 } 1566 }
1585 1567
1586 uhci_giveback_urb(uhci, qh, urb); 1568 uhci_giveback_urb(uhci, qh, urb, status);
1587 if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) 1569 if (status < 0)
1588 break; 1570 break;
1589 } 1571 }
1590 1572
@@ -1599,7 +1581,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
1599restart: 1581restart:
1600 list_for_each_entry(urbp, &qh->queue, node) { 1582 list_for_each_entry(urbp, &qh->queue, node) {
1601 urb = urbp->urb; 1583 urb = urbp->urb;
1602 if (urb->status != -EINPROGRESS) { 1584 if (urb->unlinked) {
1603 1585
1604 /* Fix up the TD links and save the toggles for 1586 /* Fix up the TD links and save the toggles for
1605 * non-Isochronous queues. For Isochronous queues, 1587 * non-Isochronous queues. For Isochronous queues,
@@ -1608,7 +1590,7 @@ restart:
1608 qh->is_stopped = 0; 1590 qh->is_stopped = 0;
1609 return; 1591 return;
1610 } 1592 }
1611 uhci_giveback_urb(uhci, qh, urb); 1593 uhci_giveback_urb(uhci, qh, urb, 0);
1612 goto restart; 1594 goto restart;
1613 } 1595 }
1614 } 1596 }