Module Name: src Committed By: jdolecek Date: Mon Apr 23 19:55:00 UTC 2018
Modified Files: src/sys/dev/usb: xhci.c xhcireg.h Log Message: enable code to only trigger usb processing when EINT is set, to avoid misinterpreting shared interrupt for another device when clearing USBSTS, actually preserve the bits which spec requires to preserve, and actually clear bit 1, which should be actually always cleared to zero by spec also #ifdef XHCI_DEBUG some unnecessary register reads this should finally resolve PR kern/53066 also for Martin To generate a diff of this commit: cvs rdiff -u -r1.89 -r1.90 src/sys/dev/usb/xhci.c cvs rdiff -u -r1.9 -r1.10 src/sys/dev/usb/xhcireg.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/usb/xhci.c diff -u src/sys/dev/usb/xhci.c:1.89 src/sys/dev/usb/xhci.c:1.90 --- src/sys/dev/usb/xhci.c:1.89 Sun Apr 22 07:47:14 2018 +++ src/sys/dev/usb/xhci.c Mon Apr 23 19:55:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: xhci.c,v 1.89 2018/04/22 07:47:14 jdolecek Exp $ */ +/* $NetBSD: xhci.c,v 1.90 2018/04/23 19:55:00 jdolecek Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.89 2018/04/22 07:47:14 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.90 2018/04/23 19:55:00 jdolecek Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -1262,24 +1262,36 @@ xhci_intr1(struct xhci_softc * const sc) usbsts = xhci_op_read_4(sc, XHCI_USBSTS); DPRINTFN(16, "USBSTS %08jx", usbsts, 0, 0, 0); -#if 0 - if ((usbsts & (XHCI_STS_EINT|XHCI_STS_PCD)) == 0) { + if ((usbsts & (XHCI_STS_HSE | XHCI_STS_EINT | XHCI_STS_PCD | + XHCI_STS_HCE)) == 0) { + DPRINTFN(16, "ignored intr not for %s", + device_xname(sc->sc_dev), 0, 0, 0); return 0; } -#endif - xhci_op_write_4(sc, XHCI_USBSTS, - usbsts & (2|XHCI_STS_EINT|XHCI_STS_PCD)); /* XXX */ + + /* + * Clear EINT and other transient flags, to not misenterpret + * next shared interrupt. Also, to avoid race, EINT must be cleared + * before XHCI_IMAN_INTR_PEND is cleared. + */ + xhci_op_write_4(sc, XHCI_USBSTS, usbsts & XHCI_STS_RSVDP0); + +#ifdef XHCI_DEBUG usbsts = xhci_op_read_4(sc, XHCI_USBSTS); DPRINTFN(16, "USBSTS %08jx", usbsts, 0, 0, 0); +#endif iman = xhci_rt_read_4(sc, XHCI_IMAN(0)); DPRINTFN(16, "IMAN0 %08jx", iman, 0, 0, 0); iman |= XHCI_IMAN_INTR_PEND; xhci_rt_write_4(sc, XHCI_IMAN(0), iman); + +#ifdef XHCI_DEBUG iman = xhci_rt_read_4(sc, XHCI_IMAN(0)); DPRINTFN(16, "IMAN0 %08jx", iman, 0, 0, 0); usbsts = xhci_op_read_4(sc, XHCI_USBSTS); DPRINTFN(16, "USBSTS %08jx", usbsts, 0, 0, 0); +#endif return 1; } Index: src/sys/dev/usb/xhcireg.h diff -u src/sys/dev/usb/xhcireg.h:1.9 src/sys/dev/usb/xhcireg.h:1.10 --- src/sys/dev/usb/xhcireg.h:1.9 Thu Jan 19 16:05:00 2017 +++ src/sys/dev/usb/xhcireg.h Mon Apr 23 19:55:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: xhcireg.h,v 1.9 2017/01/19 16:05:00 skrll Exp $ */ +/* $NetBSD: xhcireg.h,v 1.10 2018/04/23 19:55:00 jdolecek Exp $ */ /*- * Copyright (c) 2010 Hans Petter Selasky. All rights reserved. @@ -106,14 +106,17 @@ #define XHCI_USBSTS 0x04 /* XHCI status */ #define XHCI_STS_HCH 0x00000001 /* RO - Host Controller Halted */ +#define XHCI_STS_RSVDZ0 0x00000002 /* RsvdZ - 2:2 */ #define XHCI_STS_HSE 0x00000004 /* RW - Host System Error */ #define XHCI_STS_EINT 0x00000008 /* RW - Event Interrupt */ #define XHCI_STS_PCD 0x00000010 /* RW - Port Change Detect */ +#define XHCI_STS_RSVDZ1 __BITS(5, 7) /* RsvdZ - 5:7 */ #define XHCI_STS_SSS 0x00000100 /* RO - Save State Status */ #define XHCI_STS_RSS 0x00000200 /* RO - Restore State Status */ #define XHCI_STS_SRE 0x00000400 /* RW - Save/Restore Error */ #define XHCI_STS_CNR 0x00000800 /* RO - Controller Not Ready */ #define XHCI_STS_HCE 0x00001000 /* RO - Host Controller Error */ +#define XHCI_STS_RSVDP0 __BITS(13, 31) /* RsvdP - 13:31 */ #define XHCI_PAGESIZE 0x08 /* XHCI page size mask */ #define XHCI_PAGESIZE_4K 0x00000001 /* 4K Page Size */