aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/uhci-hcd.c
diff options
context:
space:
mode:
authorAlan Stern <stern@rowland.harvard.edu>2005-12-17 17:58:46 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2006-03-20 17:49:57 -0500
commitdccf4a48d47120a42382ba526f1a0848c13ba2a4 (patch)
tree788a0a9f491d1a42df1dee1781156ccfc363b6ef /drivers/usb/host/uhci-hcd.c
parent499003e815344304c7b0c93aad923ddf644d24e0 (diff)
[PATCH] UHCI: use one QH per endpoint, not per URB
This patch (as623) changes the uhci-hcd driver to make it use one QH per device endpoint, instead of a QH per URB as it does now. Numerous areas of the code are affected by this. For example, the distinction between "queued" URBs and non-"queued" URBs no longer exists; all URBs belong to a queue and some just happen to be at the queue's head. Signed-off-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/uhci-hcd.c')
-rw-r--r--drivers/usb/host/uhci-hcd.c65
1 files changed, 41 insertions, 24 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index dfe121d35887..1ff4b8806372 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -54,7 +54,7 @@
54/* 54/*
55 * Version Information 55 * Version Information
56 */ 56 */
57#define DRIVER_VERSION "v2.3" 57#define DRIVER_VERSION "v3.0"
58#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \ 58#define DRIVER_AUTHOR "Linus 'Frodo Rabbit' Torvalds, Johannes Erdfelt, \
59Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ 59Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \
60Alan Stern" 60Alan Stern"
@@ -489,15 +489,11 @@ static int uhci_start(struct usb_hcd *hcd)
489 uhci->fsbrtimeout = 0; 489 uhci->fsbrtimeout = 0;
490 490
491 spin_lock_init(&uhci->lock); 491 spin_lock_init(&uhci->lock);
492 INIT_LIST_HEAD(&uhci->qh_remove_list);
493 492
494 INIT_LIST_HEAD(&uhci->td_remove_list); 493 INIT_LIST_HEAD(&uhci->td_remove_list);
495
496 INIT_LIST_HEAD(&uhci->urb_remove_list);
497
498 INIT_LIST_HEAD(&uhci->urb_list); 494 INIT_LIST_HEAD(&uhci->urb_list);
499
500 INIT_LIST_HEAD(&uhci->complete_list); 495 INIT_LIST_HEAD(&uhci->complete_list);
496 INIT_LIST_HEAD(&uhci->idle_qh_list);
501 497
502 init_waitqueue_head(&uhci->waitqh); 498 init_waitqueue_head(&uhci->waitqh);
503 499
@@ -540,7 +536,7 @@ static int uhci_start(struct usb_hcd *hcd)
540 } 536 }
541 537
542 for (i = 0; i < UHCI_NUM_SKELQH; i++) { 538 for (i = 0; i < UHCI_NUM_SKELQH; i++) {
543 uhci->skelqh[i] = uhci_alloc_qh(uhci); 539 uhci->skelqh[i] = uhci_alloc_qh(uhci, NULL, NULL);
544 if (!uhci->skelqh[i]) { 540 if (!uhci->skelqh[i]) {
545 dev_err(uhci_dev(uhci), "unable to allocate QH\n"); 541 dev_err(uhci_dev(uhci), "unable to allocate QH\n");
546 goto err_alloc_skelqh; 542 goto err_alloc_skelqh;
@@ -557,13 +553,17 @@ static int uhci_start(struct usb_hcd *hcd)
557 uhci->skel_int16_qh->link = 553 uhci->skel_int16_qh->link =
558 uhci->skel_int8_qh->link = 554 uhci->skel_int8_qh->link =
559 uhci->skel_int4_qh->link = 555 uhci->skel_int4_qh->link =
560 uhci->skel_int2_qh->link = 556 uhci->skel_int2_qh->link = UHCI_PTR_QH |
561 cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH; 557 cpu_to_le32(uhci->skel_int1_qh->dma_handle);
562 uhci->skel_int1_qh->link = cpu_to_le32(uhci->skel_ls_control_qh->dma_handle) | UHCI_PTR_QH; 558
563 559 uhci->skel_int1_qh->link = UHCI_PTR_QH |
564 uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_fs_control_qh->dma_handle) | UHCI_PTR_QH; 560 cpu_to_le32(uhci->skel_ls_control_qh->dma_handle);
565 uhci->skel_fs_control_qh->link = cpu_to_le32(uhci->skel_bulk_qh->dma_handle) | UHCI_PTR_QH; 561 uhci->skel_ls_control_qh->link = UHCI_PTR_QH |
566 uhci->skel_bulk_qh->link = cpu_to_le32(uhci->skel_term_qh->dma_handle) | UHCI_PTR_QH; 562 cpu_to_le32(uhci->skel_fs_control_qh->dma_handle);
563 uhci->skel_fs_control_qh->link = UHCI_PTR_QH |
564 cpu_to_le32(uhci->skel_bulk_qh->dma_handle);
565 uhci->skel_bulk_qh->link = UHCI_PTR_QH |
566 cpu_to_le32(uhci->skel_term_qh->dma_handle);
567 567
568 /* This dummy TD is to work around a bug in Intel PIIX controllers */ 568 /* This dummy TD is to work around a bug in Intel PIIX controllers */
569 uhci_fill_td(uhci->term_td, 0, uhci_explen(0) | 569 uhci_fill_td(uhci->term_td, 0, uhci_explen(0) |
@@ -589,15 +589,15 @@ static int uhci_start(struct usb_hcd *hcd)
589 589
590 /* 590 /*
591 * ffs (Find First bit Set) does exactly what we need: 591 * ffs (Find First bit Set) does exactly what we need:
592 * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[6], 592 * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8],
593 * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[5], etc. 593 * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc.
594 * ffs > 6 => not on any high-period queue, so use 594 * ffs >= 7 => not on any high-period queue, so use
595 * skel_int1_qh = skelqh[7]. 595 * skel_int1_qh = skelqh[9].
596 * Add UHCI_NUMFRAMES to insure at least one bit is set. 596 * Add UHCI_NUMFRAMES to insure at least one bit is set.
597 */ 597 */
598 irq = 6 - (int) __ffs(i + UHCI_NUMFRAMES); 598 irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES);
599 if (irq < 0) 599 if (irq <= 1)
600 irq = 7; 600 irq = 9;
601 601
602 /* Only place we don't use the frame list routines */ 602 /* Only place we don't use the frame list routines */
603 uhci->frame[i] = UHCI_PTR_QH | 603 uhci->frame[i] = UHCI_PTR_QH |
@@ -767,13 +767,30 @@ static int uhci_resume(struct usb_hcd *hcd)
767} 767}
768#endif 768#endif
769 769
770/* Wait until all the URBs for a particular device/endpoint are gone */ 770/* Wait until a particular device/endpoint's QH is idle, and free it */
771static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd, 771static void uhci_hcd_endpoint_disable(struct usb_hcd *hcd,
772 struct usb_host_endpoint *ep) 772 struct usb_host_endpoint *hep)
773{ 773{
774 struct uhci_hcd *uhci = hcd_to_uhci(hcd); 774 struct uhci_hcd *uhci = hcd_to_uhci(hcd);
775 struct uhci_qh *qh;
776
777 spin_lock_irq(&uhci->lock);
778 qh = (struct uhci_qh *) hep->hcpriv;
779 if (qh == NULL)
780 goto done;
775 781
776 wait_event_interruptible(uhci->waitqh, list_empty(&ep->urb_list)); 782 while (qh->state != QH_STATE_IDLE) {
783 ++uhci->num_waiting;
784 spin_unlock_irq(&uhci->lock);
785 wait_event_interruptible(uhci->waitqh,
786 qh->state == QH_STATE_IDLE);
787 spin_lock_irq(&uhci->lock);
788 --uhci->num_waiting;
789 }
790
791 uhci_free_qh(uhci, qh);
792done:
793 spin_unlock_irq(&uhci->lock);
777} 794}
778 795
779static int uhci_hcd_get_frame_number(struct usb_hcd *hcd) 796static int uhci_hcd_get_frame_number(struct usb_hcd *hcd)