Hello,

There is a problem about using USB2.0 hub which has single-TT.
When attaching USB keyboard and USB speaker to same hub and
playing music via speaker, the sound is noisy.

Current code schedules split isochronous transfer and split interrupt
transfer to same timing, so TT cannot handle both transfers.

To reduce the conflict, change transfer schedule of split interrupt transfer.
Here is the diff. I tested this solved the problem.

Index: ehci.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ehci.c,v
retrieving revision 1.201
diff -u -p -u -r1.201 ehci.c
--- ehci.c      8 Jan 2019 13:49:47 -0000       1.201
+++ ehci.c      19 Jan 2019 06:57:30 -0000
@@ -1,4 +1,4 @@
-/*     $OpenBSD: ehci.c,v 1.201 2019/01/08 13:49:47 uaa Exp $ */
+/*     $OpenBSD: ehci.c,v 1.200 2017/05/15 10:52:08 mpi Exp $ */
 /*     $NetBSD: ehci.c,v 1.66 2004/06/30 03:11:56 mycroft Exp $        */
 
 /*
@@ -1429,15 +1429,30 @@ ehci_open(struct usbd_pipe *pipe)
                    EHCI_QH_CTL : 0) |
                    EHCI_QH_SET_NRL(naks)
                );
+               /*
+                * To reduce conflict with split isochronous transfer,
+                * schedule (split) interrupt trasnfer at latter half of
+                * 1ms frame:
+                *
+                *         |<-------------- H-Frame -------------->|
+                *         .H0  :H1   H2   H3   H4   H5   H6   H7  .H0" :H1"
+                *         .    :                                  .    :
+                * [HS]    .    :          SS        CS   CS'  CS" .    :
+                * [FS/LS] .    :               |<== >>>> >>>|     .    :
+                *         .    :                                  .    :
+                *         .B7' :B0   B1   B2   B3   B4   B5   B6  .B7  :B0"
+                *              |<-------------- B-Frame -------------->|
+                *
+                */
                sqh->qh.qh_endphub = htole32(
                    EHCI_QH_SET_MULT(1) |
-                   EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x01 : 0)
+                   EHCI_QH_SET_SMASK(xfertype == UE_INTERRUPT ? 0x08 : 0)
                );
                if (speed != EHCI_QH_SPEED_HIGH) {
                        sqh->qh.qh_endphub |= htole32(
                            EHCI_QH_SET_HUBA(hshubaddr) |
                            EHCI_QH_SET_PORT(hshubport) |
-                           EHCI_QH_SET_CMASK(0x1c) /* XXX */
+                           EHCI_QH_SET_CMASK(0xe0)
                        );
                }
                sqh->qh.qh_curqtd = htole32(EHCI_LINK_TERMINATE);

-- 
SASANO Takayoshi (JG1UAA) <[email protected]>

Reply via email to