diff options
| author | jdolecek <jdolecek@NetBSD.org> | 2018-04-23 19:55:00 +0000 |
|---|---|---|
| committer | jdolecek <jdolecek@NetBSD.org> | 2018-04-23 19:55:00 +0000 |
| commit | 80344a46d8bb0bb578495ef4ce26df13d170d98c (patch) | |
| tree | 80e8a56a8b8fc51cfa60d7ded10e6865c51d1c4a /sys/dev | |
| parent | 4b94a1002a9225da022bb4525c3a896ad44e7ad4 (diff) | |
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
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/usb/xhci.c | 26 | ||||
| -rw-r--r-- | sys/dev/usb/xhcireg.h | 5 |
2 files changed, 23 insertions, 8 deletions
diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 61995e4c00d..c363e90eaaf 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -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; } diff --git a/sys/dev/usb/xhcireg.h b/sys/dev/usb/xhcireg.h index 9a0f3af9d30..e88cfb50c29 100644 --- a/sys/dev/usb/xhcireg.h +++ b/sys/dev/usb/xhcireg.h @@ -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 */ |
