diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-07 22:23:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-02-07 22:23:21 -0500 |
commit | c96e2c92072d3e78954c961f53d8c7352f7abbd7 (patch) | |
tree | d844f26f926ff40e98e9eae0e11fd71acad81df4 /drivers/usb/host/uhci-hcd.c | |
parent | f2aca47dc3c2d0c2d5dbd972558557e74232bbce (diff) | |
parent | 64358164f5bfe5e11d4040c1eb674c29e1436ce5 (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (70 commits)
USB: remove duplicate device id from zc0301
USB: remove duplicate device id from usb_storage
USB: remove duplicate device id from keyspan
USB: remove duplicate device id from ftdi_sio
USB: remove duplicate device id from visor
USB: a bit more coding style cleanup
usbcore: trivial whitespace fixes
usb-storage: use first bulk endpoints, not last
EHCI: fix interrupt-driven remote wakeup
USB: switch ehci-hcd to new polling scheme
USB: autosuspend for usb printer driver
USB Input: Added kernel module to support all GTCO CalComp USB InterWrite School products
USB: Sierra Wireless auto set D0
USB: usb ethernet gadget recognizes HUSB2DEV
USB: list atmel husb2_udc gadget controller
USB: gadgetfs AIO tweaks
USB: gadgetfs behaves better on userspace init bug
USB: gadgetfs race fix
USB: gadgetfs simplifications
USB: gadgetfs cleanups
...
Diffstat (limited to 'drivers/usb/host/uhci-hcd.c')
-rw-r--r-- | drivers/usb/host/uhci-hcd.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index e0d4c2358b39..49b9d390b95f 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -92,6 +92,34 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state); | |||
92 | static void wakeup_rh(struct uhci_hcd *uhci); | 92 | static void wakeup_rh(struct uhci_hcd *uhci); |
93 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | 93 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); |
94 | 94 | ||
95 | /* | ||
96 | * Calculate the link pointer DMA value for the first Skeleton QH in a frame. | ||
97 | */ | ||
98 | static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) | ||
99 | { | ||
100 | int skelnum; | ||
101 | |||
102 | /* | ||
103 | * The interrupt queues will be interleaved as evenly as possible. | ||
104 | * There's not much to be done about period-1 interrupts; they have | ||
105 | * to occur in every frame. But we can schedule period-2 interrupts | ||
106 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
107 | * to 2 (mod 4), and so on. This way each frame only has two | ||
108 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
109 | * | ||
110 | * ffs (Find First bit Set) does exactly what we need: | ||
111 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
112 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
113 | * ffs >= 7 => not on any high-period queue, so use | ||
114 | * skel_int1_qh = skelqh[9]. | ||
115 | * Add in UHCI_NUMFRAMES to insure at least one bit is set. | ||
116 | */ | ||
117 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); | ||
118 | if (skelnum <= 1) | ||
119 | skelnum = 9; | ||
120 | return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle); | ||
121 | } | ||
122 | |||
95 | #include "uhci-debug.c" | 123 | #include "uhci-debug.c" |
96 | #include "uhci-q.c" | 124 | #include "uhci-q.c" |
97 | #include "uhci-hub.c" | 125 | #include "uhci-hub.c" |
@@ -631,32 +659,11 @@ static int uhci_start(struct usb_hcd *hcd) | |||
631 | /* | 659 | /* |
632 | * Fill the frame list: make all entries point to the proper | 660 | * Fill the frame list: make all entries point to the proper |
633 | * interrupt queue. | 661 | * interrupt queue. |
634 | * | ||
635 | * The interrupt queues will be interleaved as evenly as possible. | ||
636 | * There's not much to be done about period-1 interrupts; they have | ||
637 | * to occur in every frame. But we can schedule period-2 interrupts | ||
638 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
639 | * to 2 (mod 4), and so on. This way each frame only has two | ||
640 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
641 | */ | 662 | */ |
642 | for (i = 0; i < UHCI_NUMFRAMES; i++) { | 663 | for (i = 0; i < UHCI_NUMFRAMES; i++) { |
643 | int irq; | ||
644 | |||
645 | /* | ||
646 | * ffs (Find First bit Set) does exactly what we need: | ||
647 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
648 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
649 | * ffs >= 7 => not on any high-period queue, so use | ||
650 | * skel_int1_qh = skelqh[9]. | ||
651 | * Add UHCI_NUMFRAMES to insure at least one bit is set. | ||
652 | */ | ||
653 | irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES); | ||
654 | if (irq <= 1) | ||
655 | irq = 9; | ||
656 | 664 | ||
657 | /* Only place we don't use the frame list routines */ | 665 | /* Only place we don't use the frame list routines */ |
658 | uhci->frame[i] = UHCI_PTR_QH | | 666 | uhci->frame[i] = uhci_frame_skel_link(uhci, i); |
659 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); | ||
660 | } | 667 | } |
661 | 668 | ||
662 | /* | 669 | /* |