uhci-q.c (a0b458b64b2a3a4cb806dd5cd889bbf6c7e9d686) | uhci-q.c (04538a255ac8b404c20cbf15867c9829254c470f) |
---|---|
1/* 2 * Universal Host Controller Interface driver for USB. 3 * 4 * Maintainer: Alan Stern <stern@rowland.harvard.edu> 5 * 6 * (C) Copyright 1999 Linus Torvalds 7 * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com 8 * (C) Copyright 1999 Randy Dunlap 9 * (C) Copyright 1999 Georg Acher, acher@in.tum.de 10 * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de 11 * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch 12 * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at 13 * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface 14 * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). 15 * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) 16 * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu 17 */ 18 | 1/* 2 * Universal Host Controller Interface driver for USB. 3 * 4 * Maintainer: Alan Stern <stern@rowland.harvard.edu> 5 * 6 * (C) Copyright 1999 Linus Torvalds 7 * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com 8 * (C) Copyright 1999 Randy Dunlap 9 * (C) Copyright 1999 Georg Acher, acher@in.tum.de 10 * (C) Copyright 1999 Deti Fliegl, deti@fliegl.de 11 * (C) Copyright 1999 Thomas Sailer, sailer@ife.ee.ethz.ch 12 * (C) Copyright 1999 Roman Weissgaerber, weissg@vienna.at 13 * (C) Copyright 2000 Yggdrasil Computing, Inc. (port of new PCI interface 14 * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com). 15 * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c) 16 * (C) Copyright 2004-2005 Alan Stern, stern@rowland.harvard.edu 17 */ 18 |
19static void uhci_free_pending_tds(struct uhci_hcd *uhci); | |
20 21/* 22 * Technically, updating td->status here is a race, but it's not really a 23 * problem. The worst that can happen is that we set the IOC bit again 24 * generating a spurious interrupt. We could fix this by creating another 25 * QH and leaving the IOC bit always set, but then we would have to play 26 * games with the FSBR code to make sure we get the correct order in all 27 * the cases. I don't think it's worth the effort --- 18 unchanged lines hidden (view full) --- 46 td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle); 47 if (!td) 48 return NULL; 49 50 td->dma_handle = dma_handle; 51 td->frame = -1; 52 53 INIT_LIST_HEAD(&td->list); | 19 20/* 21 * Technically, updating td->status here is a race, but it's not really a 22 * problem. The worst that can happen is that we set the IOC bit again 23 * generating a spurious interrupt. We could fix this by creating another 24 * QH and leaving the IOC bit always set, but then we would have to play 25 * games with the FSBR code to make sure we get the correct order in all 26 * the cases. I don't think it's worth the effort --- 18 unchanged lines hidden (view full) --- 45 td = dma_pool_alloc(uhci->td_pool, GFP_ATOMIC, &dma_handle); 46 if (!td) 47 return NULL; 48 49 td->dma_handle = dma_handle; 50 td->frame = -1; 51 52 INIT_LIST_HEAD(&td->list); |
54 INIT_LIST_HEAD(&td->remove_list); | |
55 INIT_LIST_HEAD(&td->fl_list); 56 57 return td; 58} 59 60static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) 61{ 62 if (!list_empty(&td->list)) 63 dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); | 53 INIT_LIST_HEAD(&td->fl_list); 54 55 return td; 56} 57 58static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td) 59{ 60 if (!list_empty(&td->list)) 61 dev_warn(uhci_dev(uhci), "td %p still in list!\n", td); |
64 if (!list_empty(&td->remove_list)) 65 dev_warn(uhci_dev(uhci), "td %p still in remove_list!\n", td); | |
66 if (!list_empty(&td->fl_list)) 67 dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); 68 69 dma_pool_free(uhci->td_pool, td, td->dma_handle); 70} 71 72static inline void uhci_fill_td(struct uhci_td *td, u32 status, 73 u32 token, u32 buffer) 74{ 75 td->status = cpu_to_le32(status); 76 td->token = cpu_to_le32(token); 77 td->buffer = cpu_to_le32(buffer); 78} 79 | 62 if (!list_empty(&td->fl_list)) 63 dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td); 64 65 dma_pool_free(uhci->td_pool, td, td->dma_handle); 66} 67 68static inline void uhci_fill_td(struct uhci_td *td, u32 status, 69 u32 token, u32 buffer) 70{ 71 td->status = cpu_to_le32(status); 72 td->token = cpu_to_le32(token); 73 td->buffer = cpu_to_le32(buffer); 74} 75 |
76static void uhci_add_td_to_urbp(struct uhci_td *td, struct urb_priv *urbp) 77{ 78 list_add_tail(&td->list, &urbp->td_list); 79} 80 81static void uhci_remove_td_from_urbp(struct uhci_td *td) 82{ 83 list_del_init(&td->list); 84} 85 |
|
80/* 81 * We insert Isochronous URBs directly into the frame list at the beginning 82 */ 83static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, 84 struct uhci_td *td, unsigned framenum) 85{ 86 framenum &= (UHCI_NUMFRAMES - 1); 87 --- 328 unchanged lines hidden (view full) --- 416 urb->hcpriv = urbp; 417 418 INIT_LIST_HEAD(&urbp->node); 419 INIT_LIST_HEAD(&urbp->td_list); 420 421 return urbp; 422} 423 | 86/* 87 * We insert Isochronous URBs directly into the frame list at the beginning 88 */ 89static inline void uhci_insert_td_in_frame_list(struct uhci_hcd *uhci, 90 struct uhci_td *td, unsigned framenum) 91{ 92 framenum &= (UHCI_NUMFRAMES - 1); 93 --- 328 unchanged lines hidden (view full) --- 422 urb->hcpriv = urbp; 423 424 INIT_LIST_HEAD(&urbp->node); 425 INIT_LIST_HEAD(&urbp->td_list); 426 427 return urbp; 428} 429 |
424static void uhci_add_td_to_urb(struct urb *urb, struct uhci_td *td) 425{ 426 struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv; 427 428 list_add_tail(&td->list, &urbp->td_list); 429} 430 431static void uhci_remove_td_from_urb(struct uhci_td *td) 432{ 433 if (list_empty(&td->list)) 434 return; 435 436 list_del_init(&td->list); 437} 438 | |
439static void uhci_free_urb_priv(struct uhci_hcd *uhci, 440 struct urb_priv *urbp) 441{ 442 struct uhci_td *td, *tmp; 443 444 if (!list_empty(&urbp->node)) 445 dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", 446 urbp->urb); 447 | 430static void uhci_free_urb_priv(struct uhci_hcd *uhci, 431 struct urb_priv *urbp) 432{ 433 struct uhci_td *td, *tmp; 434 435 if (!list_empty(&urbp->node)) 436 dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n", 437 urbp->urb); 438 |
448 uhci_get_current_frame_number(uhci); 449 if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) { 450 uhci_free_pending_tds(uhci); 451 uhci->td_remove_age = uhci->frame_number; 452 } 453 454 /* Check to see if the remove list is empty. Set the IOC bit */ 455 /* to force an interrupt so we can remove the TDs. */ 456 if (list_empty(&uhci->td_remove_list)) 457 uhci_set_next_interrupt(uhci); 458 | |
459 list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { | 439 list_for_each_entry_safe(td, tmp, &urbp->td_list, list) { |
460 uhci_remove_td_from_urb(td); 461 list_add(&td->remove_list, &uhci->td_remove_list); | 440 uhci_remove_td_from_urbp(td); 441 uhci_free_td(uhci, td); |
462 } 463 464 urbp->urb->hcpriv = NULL; 465 kmem_cache_free(uhci_up_cachep, urbp); 466} 467 468static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb) 469{ --- 54 unchanged lines hidden (view full) --- 524 struct uhci_qh *qh) 525{ 526 struct uhci_td *td; 527 unsigned long destination, status; 528 int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 529 int len = urb->transfer_buffer_length; 530 dma_addr_t data = urb->transfer_dma; 531 __le32 *plink; | 442 } 443 444 urbp->urb->hcpriv = NULL; 445 kmem_cache_free(uhci_up_cachep, urbp); 446} 447 448static void uhci_inc_fsbr(struct uhci_hcd *uhci, struct urb *urb) 449{ --- 54 unchanged lines hidden (view full) --- 504 struct uhci_qh *qh) 505{ 506 struct uhci_td *td; 507 unsigned long destination, status; 508 int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 509 int len = urb->transfer_buffer_length; 510 dma_addr_t data = urb->transfer_dma; 511 __le32 *plink; |
512 struct urb_priv *urbp = urb->hcpriv; |
|
532 533 /* The "pipe" thing contains the destination in bits 8--18 */ 534 destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; 535 536 /* 3 errors, dummy TD remains inactive */ 537 status = uhci_maxerr(3); 538 if (urb->dev->speed == USB_SPEED_LOW) 539 status |= TD_CTRL_LS; 540 541 /* 542 * Build the TD for the control request setup packet 543 */ 544 td = qh->dummy_td; | 513 514 /* The "pipe" thing contains the destination in bits 8--18 */ 515 destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP; 516 517 /* 3 errors, dummy TD remains inactive */ 518 status = uhci_maxerr(3); 519 if (urb->dev->speed == USB_SPEED_LOW) 520 status |= TD_CTRL_LS; 521 522 /* 523 * Build the TD for the control request setup packet 524 */ 525 td = qh->dummy_td; |
545 uhci_add_td_to_urb(urb, td); | 526 uhci_add_td_to_urbp(td, urbp); |
546 uhci_fill_td(td, status, destination | uhci_explen(8), 547 urb->setup_dma); 548 plink = &td->link; 549 status |= TD_CTRL_ACTIVE; 550 551 /* 552 * If direction is "send", change the packet ID from SETUP (0x2D) 553 * to OUT (0xE1). Else change it from SETUP to IN (0x69) and --- 15 unchanged lines hidden (view full) --- 569 td = uhci_alloc_td(uhci); 570 if (!td) 571 goto nomem; 572 *plink = cpu_to_le32(td->dma_handle); 573 574 /* Alternate Data0/1 (start with Data1) */ 575 destination ^= TD_TOKEN_TOGGLE; 576 | 527 uhci_fill_td(td, status, destination | uhci_explen(8), 528 urb->setup_dma); 529 plink = &td->link; 530 status |= TD_CTRL_ACTIVE; 531 532 /* 533 * If direction is "send", change the packet ID from SETUP (0x2D) 534 * to OUT (0xE1). Else change it from SETUP to IN (0x69) and --- 15 unchanged lines hidden (view full) --- 550 td = uhci_alloc_td(uhci); 551 if (!td) 552 goto nomem; 553 *plink = cpu_to_le32(td->dma_handle); 554 555 /* Alternate Data0/1 (start with Data1) */ 556 destination ^= TD_TOKEN_TOGGLE; 557 |
577 uhci_add_td_to_urb(urb, td); | 558 uhci_add_td_to_urbp(td, urbp); |
578 uhci_fill_td(td, status, destination | uhci_explen(pktsze), 579 data); 580 plink = &td->link; 581 582 data += pktsze; 583 len -= pktsze; 584 } 585 --- 14 unchanged lines hidden (view full) --- 600 destination |= USB_PID_IN; 601 else 602 destination |= USB_PID_OUT; 603 604 destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ 605 606 status &= ~TD_CTRL_SPD; 607 | 559 uhci_fill_td(td, status, destination | uhci_explen(pktsze), 560 data); 561 plink = &td->link; 562 563 data += pktsze; 564 len -= pktsze; 565 } 566 --- 14 unchanged lines hidden (view full) --- 581 destination |= USB_PID_IN; 582 else 583 destination |= USB_PID_OUT; 584 585 destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ 586 587 status &= ~TD_CTRL_SPD; 588 |
608 uhci_add_td_to_urb(urb, td); | 589 uhci_add_td_to_urbp(td, urbp); |
609 uhci_fill_td(td, status | TD_CTRL_IOC, 610 destination | uhci_explen(0), 0); 611 plink = &td->link; 612 613 /* 614 * Build the new dummy TD and activate the old one 615 */ 616 td = uhci_alloc_td(uhci); --- 18 unchanged lines hidden (view full) --- 635 uhci_inc_fsbr(uhci, urb); 636 } 637 638 urb->actual_length = -8; /* Account for the SETUP packet */ 639 return 0; 640 641nomem: 642 /* Remove the dummy TD from the td_list so it doesn't get freed */ | 590 uhci_fill_td(td, status | TD_CTRL_IOC, 591 destination | uhci_explen(0), 0); 592 plink = &td->link; 593 594 /* 595 * Build the new dummy TD and activate the old one 596 */ 597 td = uhci_alloc_td(uhci); --- 18 unchanged lines hidden (view full) --- 616 uhci_inc_fsbr(uhci, urb); 617 } 618 619 urb->actual_length = -8; /* Account for the SETUP packet */ 620 return 0; 621 622nomem: 623 /* Remove the dummy TD from the td_list so it doesn't get freed */ |
643 uhci_remove_td_from_urb(qh->dummy_td); | 624 uhci_remove_td_from_urbp(qh->dummy_td); |
644 return -ENOMEM; 645} 646 647/* 648 * Common submit for bulk and interrupt 649 */ 650static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, 651 struct uhci_qh *qh) 652{ 653 struct uhci_td *td; 654 unsigned long destination, status; 655 int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 656 int len = urb->transfer_buffer_length; 657 dma_addr_t data = urb->transfer_dma; 658 __le32 *plink; | 625 return -ENOMEM; 626} 627 628/* 629 * Common submit for bulk and interrupt 630 */ 631static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, 632 struct uhci_qh *qh) 633{ 634 struct uhci_td *td; 635 unsigned long destination, status; 636 int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize); 637 int len = urb->transfer_buffer_length; 638 dma_addr_t data = urb->transfer_dma; 639 __le32 *plink; |
640 struct urb_priv *urbp = urb->hcpriv; |
|
659 unsigned int toggle; 660 661 if (len < 0) 662 return -EINVAL; 663 664 /* The "pipe" thing contains the destination in bits 8--18 */ 665 destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 666 toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), --- 21 unchanged lines hidden (view full) --- 688 } 689 690 if (plink) { 691 td = uhci_alloc_td(uhci); 692 if (!td) 693 goto nomem; 694 *plink = cpu_to_le32(td->dma_handle); 695 } | 641 unsigned int toggle; 642 643 if (len < 0) 644 return -EINVAL; 645 646 /* The "pipe" thing contains the destination in bits 8--18 */ 647 destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe); 648 toggle = usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), --- 21 unchanged lines hidden (view full) --- 670 } 671 672 if (plink) { 673 td = uhci_alloc_td(uhci); 674 if (!td) 675 goto nomem; 676 *plink = cpu_to_le32(td->dma_handle); 677 } |
696 uhci_add_td_to_urb(urb, td); | 678 uhci_add_td_to_urbp(td, urbp); |
697 uhci_fill_td(td, status, 698 destination | uhci_explen(pktsze) | 699 (toggle << TD_TOKEN_TOGGLE_SHIFT), 700 data); 701 plink = &td->link; 702 status |= TD_CTRL_ACTIVE; 703 704 data += pktsze; --- 11 unchanged lines hidden (view full) --- 716 if ((urb->transfer_flags & URB_ZERO_PACKET) && 717 usb_pipeout(urb->pipe) && len == 0 && 718 urb->transfer_buffer_length > 0) { 719 td = uhci_alloc_td(uhci); 720 if (!td) 721 goto nomem; 722 *plink = cpu_to_le32(td->dma_handle); 723 | 679 uhci_fill_td(td, status, 680 destination | uhci_explen(pktsze) | 681 (toggle << TD_TOKEN_TOGGLE_SHIFT), 682 data); 683 plink = &td->link; 684 status |= TD_CTRL_ACTIVE; 685 686 data += pktsze; --- 11 unchanged lines hidden (view full) --- 698 if ((urb->transfer_flags & URB_ZERO_PACKET) && 699 usb_pipeout(urb->pipe) && len == 0 && 700 urb->transfer_buffer_length > 0) { 701 td = uhci_alloc_td(uhci); 702 if (!td) 703 goto nomem; 704 *plink = cpu_to_le32(td->dma_handle); 705 |
724 uhci_add_td_to_urb(urb, td); | 706 uhci_add_td_to_urbp(td, urbp); |
725 uhci_fill_td(td, status, 726 destination | uhci_explen(0) | 727 (toggle << TD_TOKEN_TOGGLE_SHIFT), 728 data); 729 plink = &td->link; 730 731 toggle ^= 1; 732 } --- 20 unchanged lines hidden (view full) --- 753 qh->dummy_td = td; 754 755 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 756 usb_pipeout(urb->pipe), toggle); 757 return 0; 758 759nomem: 760 /* Remove the dummy TD from the td_list so it doesn't get freed */ | 707 uhci_fill_td(td, status, 708 destination | uhci_explen(0) | 709 (toggle << TD_TOKEN_TOGGLE_SHIFT), 710 data); 711 plink = &td->link; 712 713 toggle ^= 1; 714 } --- 20 unchanged lines hidden (view full) --- 735 qh->dummy_td = td; 736 737 usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), 738 usb_pipeout(urb->pipe), toggle); 739 return 0; 740 741nomem: 742 /* Remove the dummy TD from the td_list so it doesn't get freed */ |
761 uhci_remove_td_from_urb(qh->dummy_td); | 743 uhci_remove_td_from_urbp(qh->dummy_td); |
762 return -ENOMEM; 763} 764 765static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, 766 struct uhci_qh *qh) 767{ 768 int ret; 769 --- 55 unchanged lines hidden (view full) --- 825 ret = 0; 826 } 827 828 /* Remove all the TDs we skipped over, from tmp back to the start */ 829 while (tmp != &urbp->td_list) { 830 td = list_entry(tmp, struct uhci_td, list); 831 tmp = tmp->prev; 832 | 744 return -ENOMEM; 745} 746 747static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, 748 struct uhci_qh *qh) 749{ 750 int ret; 751 --- 55 unchanged lines hidden (view full) --- 807 ret = 0; 808 } 809 810 /* Remove all the TDs we skipped over, from tmp back to the start */ 811 while (tmp != &urbp->td_list) { 812 td = list_entry(tmp, struct uhci_td, list); 813 tmp = tmp->prev; 814 |
833 uhci_remove_td_from_urb(td); 834 list_add(&td->remove_list, &uhci->td_remove_list); | 815 uhci_remove_td_from_urbp(td); 816 uhci_free_td(uhci, td); |
835 } 836 return ret; 837} 838 839/* 840 * Common result for control, bulk, and interrupt 841 */ 842static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) --- 37 unchanged lines hidden (view full) --- 880 881 /* We received a short packet */ 882 if (urb->transfer_flags & URB_SHORT_NOT_OK) 883 ret = -EREMOTEIO; 884 else if (ctrlstat & TD_CTRL_SPD) 885 ret = 1; 886 } 887 | 817 } 818 return ret; 819} 820 821/* 822 * Common result for control, bulk, and interrupt 823 */ 824static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) --- 37 unchanged lines hidden (view full) --- 862 863 /* We received a short packet */ 864 if (urb->transfer_flags & URB_SHORT_NOT_OK) 865 ret = -EREMOTEIO; 866 else if (ctrlstat & TD_CTRL_SPD) 867 ret = 1; 868 } 869 |
888 uhci_remove_td_from_urb(td); | 870 uhci_remove_td_from_urbp(td); |
889 if (qh->post_td) | 871 if (qh->post_td) |
890 list_add(&qh->post_td->remove_list, 891 &uhci->td_remove_list); | 872 uhci_free_td(uhci, qh->post_td); |
892 qh->post_td = td; 893 894 if (ret != 0) 895 goto err; 896 } 897 return ret; 898 899err: --- 52 unchanged lines hidden (view full) --- 952 } 953 urb->start_frame &= (UHCI_NUMFRAMES - 1); 954 955 for (i = 0; i < urb->number_of_packets; i++) { 956 td = uhci_alloc_td(uhci); 957 if (!td) 958 return -ENOMEM; 959 | 873 qh->post_td = td; 874 875 if (ret != 0) 876 goto err; 877 } 878 return ret; 879 880err: --- 52 unchanged lines hidden (view full) --- 933 } 934 urb->start_frame &= (UHCI_NUMFRAMES - 1); 935 936 for (i = 0; i < urb->number_of_packets; i++) { 937 td = uhci_alloc_td(uhci); 938 if (!td) 939 return -ENOMEM; 940 |
960 uhci_add_td_to_urb(urb, td); | 941 uhci_add_td_to_urbp(td, urbp); |
961 uhci_fill_td(td, status, destination | 962 uhci_explen(urb->iso_frame_desc[i].length), 963 urb->transfer_dma + 964 urb->iso_frame_desc[i].offset); 965 } 966 967 /* Set the interrupt-on-completion flag on the last packet. */ 968 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); --- 293 unchanged lines hidden (view full) --- 1262 } 1263 1264 /* The queue is empty. The QH can become idle if it is fully 1265 * unlinked. */ 1266 else if (QH_FINISHED_UNLINKING(qh)) 1267 uhci_make_qh_idle(uhci, qh); 1268} 1269 | 942 uhci_fill_td(td, status, destination | 943 uhci_explen(urb->iso_frame_desc[i].length), 944 urb->transfer_dma + 945 urb->iso_frame_desc[i].offset); 946 } 947 948 /* Set the interrupt-on-completion flag on the last packet. */ 949 td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); --- 293 unchanged lines hidden (view full) --- 1243 } 1244 1245 /* The queue is empty. The QH can become idle if it is fully 1246 * unlinked. */ 1247 else if (QH_FINISHED_UNLINKING(qh)) 1248 uhci_make_qh_idle(uhci, qh); 1249} 1250 |
1270static void uhci_free_pending_tds(struct uhci_hcd *uhci) 1271{ 1272 struct uhci_td *td, *tmp; 1273 1274 list_for_each_entry_safe(td, tmp, &uhci->td_remove_list, remove_list) { 1275 list_del_init(&td->remove_list); 1276 1277 uhci_free_td(uhci, td); 1278 } 1279} 1280 | |
1281/* 1282 * Process events in the schedule, but only in one thread at a time 1283 */ 1284static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) 1285{ 1286 int i; 1287 struct uhci_qh *qh; 1288 --- 4 unchanged lines hidden (view full) --- 1293 } 1294 uhci->scan_in_progress = 1; 1295 rescan: 1296 uhci->need_rescan = 0; 1297 1298 uhci_clear_next_interrupt(uhci); 1299 uhci_get_current_frame_number(uhci); 1300 | 1251/* 1252 * Process events in the schedule, but only in one thread at a time 1253 */ 1254static void uhci_scan_schedule(struct uhci_hcd *uhci, struct pt_regs *regs) 1255{ 1256 int i; 1257 struct uhci_qh *qh; 1258 --- 4 unchanged lines hidden (view full) --- 1263 } 1264 uhci->scan_in_progress = 1; 1265 rescan: 1266 uhci->need_rescan = 0; 1267 1268 uhci_clear_next_interrupt(uhci); 1269 uhci_get_current_frame_number(uhci); 1270 |
1301 if (uhci->frame_number + uhci->is_stopped != uhci->td_remove_age) 1302 uhci_free_pending_tds(uhci); 1303 | |
1304 /* Go through all the QH queues and process the URBs in each one */ 1305 for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) { 1306 uhci->next_qh = list_entry(uhci->skelqh[i]->node.next, 1307 struct uhci_qh, node); 1308 while ((qh = uhci->next_qh) != uhci->skelqh[i]) { 1309 uhci->next_qh = list_entry(qh->node.next, 1310 struct uhci_qh, node); 1311 uhci_scan_qh(uhci, qh, regs); 1312 } 1313 } 1314 1315 if (uhci->need_rescan) 1316 goto rescan; 1317 uhci->scan_in_progress = 0; 1318 | 1271 /* Go through all the QH queues and process the URBs in each one */ 1272 for (i = 0; i < UHCI_NUM_SKELQH - 1; ++i) { 1273 uhci->next_qh = list_entry(uhci->skelqh[i]->node.next, 1274 struct uhci_qh, node); 1275 while ((qh = uhci->next_qh) != uhci->skelqh[i]) { 1276 uhci->next_qh = list_entry(qh->node.next, 1277 struct uhci_qh, node); 1278 uhci_scan_qh(uhci, qh, regs); 1279 } 1280 } 1281 1282 if (uhci->need_rescan) 1283 goto rescan; 1284 uhci->scan_in_progress = 0; 1285 |
1319 /* If the controller is stopped, we can finish these off right now */ 1320 if (uhci->is_stopped) 1321 uhci_free_pending_tds(uhci); 1322 1323 if (list_empty(&uhci->td_remove_list) && 1324 list_empty(&uhci->skel_unlink_qh->node)) | 1286 if (list_empty(&uhci->skel_unlink_qh->node)) |
1325 uhci_clear_next_interrupt(uhci); 1326 else 1327 uhci_set_next_interrupt(uhci); 1328} 1329 1330static void check_fsbr(struct uhci_hcd *uhci) 1331{ 1332 /* For now, don't scan URBs for FSBR timeouts. 1333 * Add it back in later... */ 1334 1335 /* Really disable FSBR */ 1336 if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) { 1337 uhci->fsbrtimeout = 0; 1338 uhci->skel_term_qh->link = UHCI_PTR_TERM; 1339 } 1340} | 1287 uhci_clear_next_interrupt(uhci); 1288 else 1289 uhci_set_next_interrupt(uhci); 1290} 1291 1292static void check_fsbr(struct uhci_hcd *uhci) 1293{ 1294 /* For now, don't scan URBs for FSBR timeouts. 1295 * Add it back in later... */ 1296 1297 /* Really disable FSBR */ 1298 if (!uhci->fsbr && uhci->fsbrtimeout && time_after_eq(jiffies, uhci->fsbrtimeout)) { 1299 uhci->fsbrtimeout = 0; 1300 uhci->skel_term_qh->link = UHCI_PTR_TERM; 1301 } 1302} |