Messages in this thread Patch in this message |  | | | Date | Wed, 11 Feb 2004 14:40:09 -0500 (EST) | | From | Alan Stern <> | | Subject | Re: [PATCH] Slight optimisation of the uhci-hcd init code |
Eric, Johannes:
Thought you might like to see this... I need to make sure it works right, and then it's going in.
Alan Stern
===== uhci-hcd.c 1.80 vs edited ===== --- 1.80/drivers/usb/host/uhci-hcd.c Tue Feb 10 00:33:10 2004 +++ edited/drivers/usb/host/uhci-hcd.c Wed Feb 11 14:34:51 2004 @@ -2336,16 +2336,17 @@ } /* - * 8 Interrupt queues; link int2 to int1, int4 to int2, etc + * 8 Interrupt queues; link all higher int queues to int1, * then link int1 to control and control to bulk */ - uhci->skel_int128_qh->link = cpu_to_le32(uhci->skel_int64_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int64_qh->link = cpu_to_le32(uhci->skel_int32_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int32_qh->link = cpu_to_le32(uhci->skel_int16_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int16_qh->link = cpu_to_le32(uhci->skel_int8_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int8_qh->link = cpu_to_le32(uhci->skel_int4_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int4_qh->link = cpu_to_le32(uhci->skel_int2_qh->dma_handle) | UHCI_PTR_QH; - uhci->skel_int2_qh->link = cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH; + uhci->skel_int128_qh->link = + uhci->skel_int64_qh->link = + uhci->skel_int32_qh->link = + uhci->skel_int16_qh->link = + uhci->skel_int8_qh->link = + uhci->skel_int4_qh->link = + uhci->skel_int2_qh->link = + cpu_to_le32(uhci->skel_int1_qh->dma_handle) | UHCI_PTR_QH; uhci->skel_int1_qh->link = cpu_to_le32(uhci->skel_ls_control_qh->dma_handle) | UHCI_PTR_QH; uhci->skel_ls_control_qh->link = cpu_to_le32(uhci->skel_hs_control_qh->dma_handle) | UHCI_PTR_QH; @@ -2361,39 +2362,33 @@ uhci->skel_term_qh->element = cpu_to_le32(uhci->term_td->dma_handle); /* - * Fill the frame list: make all entries point to - * the proper interrupt queue. + * Fill the frame list: make all entries point to the proper + * interrupt queue. * - * This is probably silly, but it's a simple way to - * scatter the interrupt queues in a way that gives - * us a reasonable dynamic range for irq latencies. + * The interrupt queues will be interleaved as evenly as possible. + * There's not much to be done about period-1 interrupts; they have + * to occur in every frame. But we can schedule period-2 interrupts + * in odd-numbered frames, period-4 interrupts in frames congruent + * to 2 (mod 4), and so on. This way each frame only has two + * interrupt QHs, which will help spread out bandwidth utilization. */ for (i = 0; i < UHCI_NUMFRAMES; i++) { - int irq = 0; + int irq; - if (i & 1) { - irq++; - if (i & 2) { - irq++; - if (i & 4) { - irq++; - if (i & 8) { - irq++; - if (i & 16) { - irq++; - if (i & 32) { - irq++; - if (i & 64) - irq++; - } - } - } - } - } - } + /* + * ffs (Find First bit Set) does exactly what we need: + * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[6], + * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[5], etc. + * ffs > 6 => not on any high-period queue, so use + * skel_int1_qh = skelqh[7]. + * Add UHCI_NUMFRAMES to insure at least one bit is set. + */ + irq = 6 - (int) __ffs(i + UHCI_NUMFRAMES); + if (irq < 0) + irq = 7; /* Only place we don't use the frame list routines */ - uhci->fl->frame[i] = cpu_to_le32(uhci->skelqh[7 - irq]->dma_handle); + uhci->fl->frame[i] = cpu_to_le32(uhci->skelqh[irq]->dma_handle); } start_hc(uhci); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |