diff options
Diffstat (limited to 'drivers/usb/host/uhci-q.c')
-rw-r--r-- | drivers/usb/host/uhci-q.c | 70 |
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 | ||
1378 | static int uhci_urb_enqueue(struct usb_hcd *hcd, | 1373 | static 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, | |||
1440 | err_submit_failed: | 1434 | err_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 | |||
1444 | err_no_qh: | 1437 | err_no_qh: |
1445 | uhci_free_urb_priv(uhci, urbp); | 1438 | uhci_free_urb_priv(uhci, urbp); |
1446 | |||
1447 | done: | 1439 | done: |
1440 | if (ret) | ||
1441 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1442 | done_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 | ||
1452 | static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 1447 | static 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 | ||
1478 | done: | 1474 | done: |
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 | */ |
1486 | static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, | 1482 | static 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) | |||
1599 | restart: | 1581 | restart: |
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 | } |