NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/51395: USB Ethernet makes xhci hang
The following reply was made to PR kern/51395; it has been noted by GNATS.
From: Takahiro Hayashi <t425hash%gmail.com@localhost>
To: gnats-bugs%NetBSD.org@localhost, kern-bug-people%netbsd.org@localhost,
gnats-admin%netbsd.org@localhost, netbsd-bugs%netbsd.org@localhost,
Benny Siegert <bsiegert%gmail.com@localhost>
Cc:
Subject: Re: kern/51395: USB Ethernet makes xhci hang
Date: Mon, 8 Aug 2016 22:45:02 +0900
This is a multi-part message in MIME format.
--------------D0B31FF0B77670F21EA67021
Content-Type: text/plain; charset=windows-1252; format=flowed
Content-Transfer-Encoding: 7bit
I've found that the previous fix was imcomplete.
Can you try attached patch?
This patch tries to put Link TRB at the last of ring.
This lacks handling that first TRB should be written at last.
Thank you for reporting this problem.
--
t-hash
--------------D0B31FF0B77670F21EA67021
Content-Type: text/plain; charset=UTF-8;
name="x-linktrb.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="x-linktrb.diff"
--- sys/dev/usb/xhci.c.orig 2016-07-18 07:07:53.000000000 +0900
+++ sys/dev/usb/xhci.c 2016-08-08 22:06:19.000000000 +0900
@@ -2374,25 +2397,24 @@ xhci_ring_put(struct xhci_softc * const
* The code should write the 'cycle' bit on the link trb AFTER
* adding the other trb.
*/
- if (ri + ntrbs >= (xr->xr_ntrb - 1)) {
- parameter = xhci_ring_trbp(xr, 0);
- status = 0;
- control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) |
- XHCI_TRB_3_TC_BIT | (cs ? XHCI_TRB_3_CYCLE_BIT : 0);
- xhci_trb_put(&xr->xr_trb[ri], parameter, status, control);
- usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1,
- BUS_DMASYNC_PREWRITE);
- xr->xr_cookies[ri] = NULL;
- xr->xr_ep = 0;
- xr->xr_cs ^= 1;
- ri = xr->xr_ep;
- cs = xr->xr_cs;
- }
-
- ri++;
+ for (i = 0; i < ntrbs; ) {
+ if (ri >= (xr->xr_ntrb - 1)) {
+ parameter = xhci_ring_trbp(xr, 0);
+ status = 0;
+ control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) |
+ XHCI_TRB_3_TC_BIT | (cs ? XHCI_TRB_3_CYCLE_BIT : 0);
+ xhci_trb_put(&xr->xr_trb[ri], parameter, status,
+ control);
+ usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri,
+ XHCI_TRB_SIZE * 1, BUS_DMASYNC_PREWRITE);
+ xr->xr_cookies[ri] = NULL;
+ xr->xr_ep = 0;
+ xr->xr_cs ^= 1;
+ ri = xr->xr_ep;
+ cs = xr->xr_cs;
+ continue;
+ }
- /* Write any subsequent TRB first */
- for (i = 1; i < ntrbs; i++) {
parameter = trbs[i].trb_0;
status = trbs[i].trb_2;
control = trbs[i].trb_3;
@@ -2408,25 +2430,9 @@ xhci_ring_put(struct xhci_softc * const
BUS_DMASYNC_PREWRITE);
xr->xr_cookies[ri] = cookie;
ri++;
+ i++;
}
- /* Write the first TRB last */
- i = 0;
- parameter = trbs[i].trb_0;
- status = trbs[i].trb_2;
- control = trbs[i].trb_3;
-
- if (xr->xr_cs) {
- control |= XHCI_TRB_3_CYCLE_BIT;
- } else {
- control &= ~XHCI_TRB_3_CYCLE_BIT;
- }
-
- xhci_trb_put(&xr->xr_trb[xr->xr_ep], parameter, status, control);
- usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * xr->xr_ep, XHCI_TRB_SIZE * 1,
- BUS_DMASYNC_PREWRITE);
- xr->xr_cookies[xr->xr_ep] = cookie;
-
xr->xr_ep = ri;
xr->xr_cs = cs;
--------------D0B31FF0B77670F21EA67021--
Home |
Main Index |
Thread Index |
Old Index