Sun May 23 11:49:45 2021 UTC ()
xhci(4): Draft suspend/resume.

Work almost entirely done and tested by maya@ based on xhci 1.2 spec;
tidied up and tweaked by me.

Not sure about issuing Stop Endpoint commands or ensuring the Command
Ring is in the Stopped or Idle state, but this seems to work as is,
so it's already an improvement over what we had before which was no
xhci suspend/resume at all.

In particular, it's not clear to us:

- if we don't have any pending USB activity whether we need to issue
  the Stop Endpoints or quiesce the command ring; but

- if we do have any pending USB activity whether issuing Stop
  Endpoint is enough or whether we also need to do anything to
  synchronize with other software logic to quiesce it too.


(riastradh)
diff -r1.138 -r1.139 src/sys/dev/usb/xhci.c
diff -r1.18 -r1.19 src/sys/dev/usb/xhcireg.h
diff -r1.17 -r1.18 src/sys/dev/usb/xhcivar.h

cvs diff -r1.138 -r1.139 src/sys/dev/usb/xhci.c (expand / switch to unified diff)

--- src/sys/dev/usb/xhci.c 2021/01/05 18:00:21 1.138
+++ src/sys/dev/usb/xhci.c 2021/05/23 11:49:45 1.139
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xhci.c,v 1.138 2021/01/05 18:00:21 skrll Exp $ */ 1/* $NetBSD: xhci.c,v 1.139 2021/05/23 11:49:45 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2013 Jonathan A. Kollasch 4 * Copyright (c) 2013 Jonathan A. Kollasch
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -24,27 +24,27 @@ @@ -24,27 +24,27 @@
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * USB rev 2.0 and rev 3.1 specification 30 * USB rev 2.0 and rev 3.1 specification
31 * http://www.usb.org/developers/docs/ 31 * http://www.usb.org/developers/docs/
32 * xHCI rev 1.1 specification 32 * xHCI rev 1.1 specification
33 * http://www.intel.com/technology/usb/spec.htm 33 * http://www.intel.com/technology/usb/spec.htm
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.138 2021/01/05 18:00:21 skrll Exp $"); 37__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.139 2021/05/23 11:49:45 riastradh Exp $");
38 38
39#ifdef _KERNEL_OPT 39#ifdef _KERNEL_OPT
40#include "opt_usb.h" 40#include "opt_usb.h"
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/kmem.h> 46#include <sys/kmem.h>
47#include <sys/device.h> 47#include <sys/device.h>
48#include <sys/select.h> 48#include <sys/select.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/queue.h> 50#include <sys/queue.h>
@@ -378,47 +378,45 @@ xhci_op_write_8(const struct xhci_softc  @@ -378,47 +378,45 @@ xhci_op_write_8(const struct xhci_softc
378static inline uint32_t 378static inline uint32_t
379xhci_rt_read_4(const struct xhci_softc * const sc, bus_size_t offset) 379xhci_rt_read_4(const struct xhci_softc * const sc, bus_size_t offset)
380{ 380{
381 return bus_space_read_4(sc->sc_iot, sc->sc_rbh, offset); 381 return bus_space_read_4(sc->sc_iot, sc->sc_rbh, offset);
382} 382}
383 383
384static inline void 384static inline void
385xhci_rt_write_4(const struct xhci_softc * const sc, bus_size_t offset, 385xhci_rt_write_4(const struct xhci_softc * const sc, bus_size_t offset,
386 uint32_t value) 386 uint32_t value)
387{ 387{
388 bus_space_write_4(sc->sc_iot, sc->sc_rbh, offset, value); 388 bus_space_write_4(sc->sc_iot, sc->sc_rbh, offset, value);
389} 389}
390 390
391#if 0 /* unused */ 
392static inline uint64_t 391static inline uint64_t
393xhci_rt_read_8(const struct xhci_softc * const sc, bus_size_t offset) 392xhci_rt_read_8(const struct xhci_softc * const sc, bus_size_t offset)
394{ 393{
395 uint64_t value; 394 uint64_t value;
396 395
397 if (XHCI_HCC_AC64(sc->sc_hcc)) { 396 if (XHCI_HCC_AC64(sc->sc_hcc)) {
398#ifdef XHCI_USE_BUS_SPACE_8 397#ifdef XHCI_USE_BUS_SPACE_8
399 value = bus_space_read_8(sc->sc_iot, sc->sc_rbh, offset); 398 value = bus_space_read_8(sc->sc_iot, sc->sc_rbh, offset);
400#else 399#else
401 value = bus_space_read_4(sc->sc_iot, sc->sc_rbh, offset); 400 value = bus_space_read_4(sc->sc_iot, sc->sc_rbh, offset);
402 value |= (uint64_t)bus_space_read_4(sc->sc_iot, sc->sc_rbh, 401 value |= (uint64_t)bus_space_read_4(sc->sc_iot, sc->sc_rbh,
403 offset + 4) << 32; 402 offset + 4) << 32;
404#endif 403#endif
405 } else { 404 } else {
406 value = bus_space_read_4(sc->sc_iot, sc->sc_rbh, offset); 405 value = bus_space_read_4(sc->sc_iot, sc->sc_rbh, offset);
407 } 406 }
408 407
409 return value; 408 return value;
410} 409}
411#endif /* unused */ 
412 410
413static inline void 411static inline void
414xhci_rt_write_8(const struct xhci_softc * const sc, bus_size_t offset, 412xhci_rt_write_8(const struct xhci_softc * const sc, bus_size_t offset,
415 uint64_t value) 413 uint64_t value)
416{ 414{
417 if (XHCI_HCC_AC64(sc->sc_hcc)) { 415 if (XHCI_HCC_AC64(sc->sc_hcc)) {
418#ifdef XHCI_USE_BUS_SPACE_8 416#ifdef XHCI_USE_BUS_SPACE_8
419 bus_space_write_8(sc->sc_iot, sc->sc_rbh, offset, value); 417 bus_space_write_8(sc->sc_iot, sc->sc_rbh, offset, value);
420#else 418#else
421 bus_space_write_4(sc->sc_iot, sc->sc_rbh, offset + 0, 419 bus_space_write_4(sc->sc_iot, sc->sc_rbh, offset + 0,
422 (value >> 0) & 0xffffffff); 420 (value >> 0) & 0xffffffff);
423 bus_space_write_4(sc->sc_iot, sc->sc_rbh, offset + 4, 421 bus_space_write_4(sc->sc_iot, sc->sc_rbh, offset + 4,
424 (value >> 32) & 0xffffffff); 422 (value >> 32) & 0xffffffff);
@@ -688,35 +686,377 @@ xhci_activate(device_t self, enum devact @@ -688,35 +686,377 @@ xhci_activate(device_t self, enum devact
688{ 686{
689 struct xhci_softc * const sc = device_private(self); 687 struct xhci_softc * const sc = device_private(self);
690 688
691 switch (act) { 689 switch (act) {
692 case DVACT_DEACTIVATE: 690 case DVACT_DEACTIVATE:
693 sc->sc_dying = true; 691 sc->sc_dying = true;
694 return 0; 692 return 0;
695 default: 693 default:
696 return EOPNOTSUPP; 694 return EOPNOTSUPP;
697 } 695 }
698} 696}
699 697
700bool 698bool
701xhci_suspend(device_t dv, const pmf_qual_t *qual) 699xhci_suspend(device_t self, const pmf_qual_t *qual)
702{ 700{
703 return false; 701 struct xhci_softc * const sc = device_private(self);
 702 size_t i, j, bn;
 703 int port;
 704 uint32_t v;
 705
 706 XHCIHIST_FUNC(); XHCIHIST_CALLED();
 707
 708 /*
 709 * First, suspend all the ports:
 710 *
 711 * xHCI Requirements Specification 1.2, May 2019, Sec. 4.15:
 712 * Suspend-Resume, pp. 276-283
 713 * https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf#page=276
 714 */
 715 for (bn = 0; bn < 2; bn++) {
 716 for (i = 1; i <= sc->sc_rhportcount[bn]; i++) {
 717 /* 4.15.1: Port Suspend. */
 718 port = XHCI_PORTSC(xhci_rhport2ctlrport(sc, bn, i));
 719
 720 /*
 721 * `System software places individual ports
 722 * into suspend mode by writing a ``3'' into
 723 * the appropriate PORTSC register Port Link
 724 * State (PLS) field (refer to Section 5.4.8).
 725 * Software should only set the PLS field to
 726 * ``3'' when the port is in the Enabled
 727 * state.'
 728 *
 729 * `Software should not attempt to suspend a
 730 * port unless the port reports that it is in
 731 * the enabled (PED = ``1''; PLS < ``3'')
 732 * state (refer to Section 5.4.8 for more
 733 * information about PED and PLS).'
 734 */
 735 v = xhci_op_read_4(sc, port);
 736 if (((v & XHCI_PS_PED) == 0) ||
 737 XHCI_PS_PLS_GET(v) >= XHCI_PS_PLS_U3)
 738 continue;
 739 v &= ~(XHCI_PS_PLS_MASK | XHCI_PS_CLEAR);
 740 v |= XHCI_PS_LWS | XHCI_PS_PLS_SET(XHCI_PS_PLS_SETU3);
 741 xhci_op_write_4(sc, port, v);
 742
 743 /*
 744 * `When the PLS field is written with U3
 745 * (``3''), the status of the PLS bit will not
 746 * change to the target U state U3 until the
 747 * suspend signaling has completed to the
 748 * attached device (which may be as long as
 749 * 10ms.).'
 750 *
 751 * `Software is required to wait for U3
 752 * transitions to complete before it puts the
 753 * xHC into a low power state, and before
 754 * resuming the port.'
 755 *
 756 * XXX Take advantage of the technique to
 757 * reduce polling on host controllers that
 758 * support the U3C capability.
 759 */
 760 for (j = 0; j < XHCI_WAIT_PLS_U3; j++) {
 761 v = xhci_op_read_4(sc, port);
 762 if (XHCI_PS_PLS_GET(v) == XHCI_PS_PLS_U3)
 763 break;
 764 usb_delay_ms(&sc->sc_bus, 1);
 765 }
 766 if (j == XHCI_WAIT_PLS_U3) {
 767 device_printf(self,
 768 "suspend timeout on bus %zu port %zu\n",
 769 bn, i);
 770 return false;
 771 }
 772 }
 773 }
 774
 775 /*
 776 * xHCI Requirements Specification 1.2, May 2019, Sec. 4.23.2:
 777 * xHCI Power Management, p. 342
 778 * https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf#page=342
 779 */
 780
 781 /*
 782 * `1. Stop all USB activity by issuing Stop Endpoint Commands
 783 * for Busy endpoints in the Running state. If the Force
 784 * Save Context Capability (FSC = ``0'') is not supported,
 785 * then Stop Endpoint Commands shall be issued for all Idle
 786 * endpoints in the Running state as well. The Stop
 787 * Endpoint Command causes the xHC to update the respective
 788 * Endpoint or Stream Contexts in system memory, e.g. the
 789 * TR Dequeue Pointer, DCS, etc. fields. Refer to
 790 * Implementation Note "0".'
 791 *
 792 * XXX Not entirely sure if this is necessary for us; also it
 793 * probably has to happen before suspending the ports.
 794 */
 795
 796 /*
 797 * `2. Ensure that the Command Ring is in the Stopped state
 798 * (CRR = ``0'') or Idle (i.e. the Command Transfer Ring is
 799 * empty), and all Command Completion Events associated
 800 * with them have been received.'
 801 *
 802 * XXX
 803 */
 804
 805 /* `3. Stop the controller by setting Run/Stop (R/S) = ``0''.' */
 806 xhci_op_write_4(sc, XHCI_USBCMD,
 807 xhci_op_read_4(sc, XHCI_USBCMD) & ~XHCI_CMD_RS);
 808
 809 /*
 810 * `4. Read the Operational Runtime, and VTIO registers in the
 811 * following order: USBCMD, DNCTRL, DCBAAP, CONFIG, ERSTSZ,
 812 * ERSTBA, ERDP, IMAN, IMOD, and VTIO and save their
 813 * state.'
 814 *
 815 * (We don't use VTIO here (XXX for now?).)
 816 */
 817 sc->sc_regs.usbcmd = xhci_op_read_4(sc, XHCI_USBCMD);
 818 sc->sc_regs.dnctrl = xhci_op_read_4(sc, XHCI_DNCTRL);
 819 sc->sc_regs.dcbaap = xhci_op_read_8(sc, XHCI_DCBAAP);
 820 sc->sc_regs.config = xhci_op_read_4(sc, XHCI_CONFIG);
 821 sc->sc_regs.erstsz0 = xhci_rt_read_4(sc, XHCI_ERSTSZ(0));
 822 sc->sc_regs.erstba0 = xhci_rt_read_8(sc, XHCI_ERSTBA(0));
 823 sc->sc_regs.erdp0 = xhci_rt_read_8(sc, XHCI_ERDP(0));
 824 sc->sc_regs.iman0 = xhci_rt_read_4(sc, XHCI_IMAN(0));
 825 sc->sc_regs.imod0 = xhci_rt_read_4(sc, XHCI_IMOD(0));
 826
 827 /*
 828 * `5. Set the Controller Save State (CSS) flag in the USBCMD
 829 * register (5.4.1)...'
 830 */
 831 xhci_op_write_4(sc, XHCI_USBCMD,
 832 xhci_op_read_4(sc, XHCI_USBCMD) | XHCI_CMD_CSS);
 833
 834 /*
 835 * `...and wait for the Save State Status (SSS) flag in the
 836 * USBSTS register (5.4.2) to transition to ``0''.'
 837 */
 838 for (i = 0; i < XHCI_WAIT_SSS; i++) {
 839 if ((xhci_op_read_4(sc, XHCI_USBSTS) & XHCI_STS_SSS) == 0)
 840 break;
 841 usb_delay_ms(&sc->sc_bus, 1);
 842 }
 843 if (i >= XHCI_WAIT_SSS) {
 844 device_printf(self, "suspend timeout, USBSTS.SSS\n");
 845 /*
 846 * Just optimistically go on and check SRE anyway --
 847 * what's the worst that could happen?
 848 */
 849 }
 850
 851 /*
 852 * `Note: After a Save or Restore operation completes, the
 853 * Save/Restore Error (SRE) flag in the USBSTS register should
 854 * be checked to ensure that the operation completed
 855 * successfully.'
 856 */
 857 if (xhci_op_read_4(sc, XHCI_USBSTS) & XHCI_STS_SRE) {
 858 device_printf(self, "suspend error, USBSTS.SRE\n");
 859 return false;
 860 }
 861
 862 return true;
704} 863}
705 864
706bool 865bool
707xhci_resume(device_t dv, const pmf_qual_t *qual) 866xhci_resume(device_t self, const pmf_qual_t *qual)
708{ 867{
709 return false; 868 struct xhci_softc * const sc = device_private(self);
 869 size_t i, j, bn, dci;
 870 int port;
 871 uint32_t v;
 872
 873 XHCIHIST_FUNC(); XHCIHIST_CALLED();
 874
 875 /*
 876 * xHCI Requirements Specification 1.2, May 2019, Sec. 4.23.2:
 877 * xHCI Power Management, p. 343
 878 * https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf#page=343
 879 */
 880
 881 /*
 882 * `4. Restore the Operational Runtime, and VTIO registers with
 883 * their previously saved state in the following order:
 884 * DNCTRL, DCBAAP, CONFIG, ERSTSZ, ERSTBA, ERDP, IMAN,
 885 * IMOD, and VTIO.'
 886 *
 887 * (We don't use VTIO here (for now?).)
 888 */
 889 xhci_op_write_4(sc, XHCI_USBCMD, sc->sc_regs.usbcmd);
 890 xhci_op_write_4(sc, XHCI_DNCTRL, sc->sc_regs.dnctrl);
 891 xhci_op_write_8(sc, XHCI_DCBAAP, sc->sc_regs.dcbaap);
 892 xhci_op_write_4(sc, XHCI_CONFIG, sc->sc_regs.config);
 893 xhci_rt_write_4(sc, XHCI_ERSTSZ(0), sc->sc_regs.erstsz0);
 894 xhci_rt_write_8(sc, XHCI_ERSTBA(0), sc->sc_regs.erstba0);
 895 xhci_rt_write_8(sc, XHCI_ERDP(0), sc->sc_regs.erdp0);
 896 xhci_rt_write_4(sc, XHCI_IMAN(0), sc->sc_regs.iman0);
 897 xhci_rt_write_4(sc, XHCI_IMOD(0), sc->sc_regs.imod0);
 898
 899 memset(&sc->sc_regs, 0, sizeof(sc->sc_regs)); /* paranoia */
 900
 901 /*
 902 * `5. Set the Controller Restore State (CRS) flag in the
 903 * USBCMD register (5.4.1) to ``1''...'
 904 */
 905 xhci_op_write_4(sc, XHCI_USBCMD,
 906 xhci_op_read_4(sc, XHCI_USBCMD) | XHCI_CMD_CRS);
 907
 908 /*
 909 * `...and wait for the Restore State Status (RSS) in the
 910 * USBSTS register (5.4.2) to transition to ``0''.'
 911 */
 912 for (i = 0; i < XHCI_WAIT_RSS; i++) {
 913 if ((xhci_op_read_4(sc, XHCI_USBSTS) & XHCI_STS_RSS) == 0)
 914 break;
 915 usb_delay_ms(&sc->sc_bus, 1);
 916 }
 917 if (i >= XHCI_WAIT_RSS) {
 918 device_printf(self, "suspend timeout, USBSTS.RSS\n");
 919 return false;
 920 }
 921
 922 /*
 923 * `6. Reinitialize the Command Ring, i.e. so its Cycle bits
 924 * are consistent with the RCS values to be written to the
 925 * CRCR.'
 926 *
 927 * XXX Hope just zeroing it is good enough!
 928 */
 929 xhci_host_dequeue(sc->sc_cr);
 930
 931 /*
 932 * `7. Write the CRCR with the address and RCS value of the
 933 * reinitialized Command Ring. Note that this write will
 934 * cause the Command Ring to restart at the address
 935 * specified by the CRCR.'
 936 */
 937 xhci_op_write_8(sc, XHCI_CRCR, xhci_ring_trbp(sc->sc_cr, 0) |
 938 sc->sc_cr->xr_cs);
 939
 940 /*
 941 * `8. Enable the controller by setting Run/Stop (R/S) =
 942 * ``1''.'
 943 */
 944 xhci_op_write_4(sc, XHCI_USBCMD,
 945 xhci_op_read_4(sc, XHCI_USBCMD) | XHCI_CMD_RS);
 946
 947 /*
 948 * `9. Software shall walk the USB topology and initialize each
 949 * of the xHC PORTSC, PORTPMSC, and PORTLI registers, and
 950 * external hub ports attached to USB devices.'
 951 *
 952 * This follows the procedure in 4.15 `Suspend-Resume', 4.15.2
 953 * `Port Resume', 4.15.2.1 `Host Initiated'.
 954 *
 955 * XXX We should maybe batch up initiating the state
 956 * transitions, and then wait for them to complete all at once.
 957 */
 958 for (bn = 0; bn < 2; bn++) {
 959 for (i = 1; i <= sc->sc_rhportcount[bn]; i++) {
 960 port = XHCI_PORTSC(xhci_rhport2ctlrport(sc, bn, i));
 961
 962 /* `When a port is in the U3 state: ...' */
 963 v = xhci_op_read_4(sc, port);
 964 if (XHCI_PS_PLS_GET(v) != XHCI_PS_PLS_U3)
 965 continue;
 966
 967 /*
 968 * `For a USB2 protocol port, software shall
 969 * write a ``15'' (Resume) to the PLS field to
 970 * initiate resume signaling. The port shall
 971 * transition to the Resume substate and the
 972 * xHC shall transmit the resume signaling
 973 * within 1ms (T_URSM). Software shall ensure
 974 * that resume is signaled for at least 20ms
 975 * (T_DRSMDN). Software shall start timing
 976 * T_DRSMDN from the write of ``15'' (Resume)
 977 * to PLS.'
 978 */
 979 if (bn == 1) {
 980 KASSERT(sc->sc_bus2.ub_revision == USBREV_2_0);
 981 v &= ~(XHCI_PS_PLS_MASK | XHCI_PS_CLEAR);
 982 v |= XHCI_PS_LWS;
 983 v |= XHCI_PS_PLS_SET(XHCI_PS_PLS_SETRESUME);
 984 xhci_op_write_4(sc, port, v);
 985 usb_delay_ms(&sc->sc_bus, 20);
 986 } else {
 987 KASSERT(sc->sc_bus.ub_revision > USBREV_2_0);
 988 }
 989
 990 /*
 991 * `For a USB3 protocol port [and a USB2
 992 * protocol port after transitioning to
 993 * Resume], software shall write a ``0'' (U0)
 994 * to the PLS field...'
 995 */
 996 v = xhci_op_read_4(sc, port);
 997 v &= ~(XHCI_PS_PLS_MASK | XHCI_PS_CLEAR);
 998 v |= XHCI_PS_LWS | XHCI_PS_PLS_SET(XHCI_PS_PLS_SETU0);
 999 xhci_op_write_4(sc, port, v);
 1000
 1001 for (j = 0; j < XHCI_WAIT_PLS_U0; j++) {
 1002 v = xhci_op_read_4(sc, port);
 1003 if (XHCI_PS_PLS_GET(v) == XHCI_PS_PLS_U0)
 1004 break;
 1005 usb_delay_ms(&sc->sc_bus, 1);
 1006 }
 1007 if (j == XHCI_WAIT_PLS_U0) {
 1008 device_printf(self,
 1009 "resume timeout on bus %zu port %zu\n",
 1010 bn, i);
 1011 return false;
 1012 }
 1013 }
 1014 }
 1015
 1016 /*
 1017 * `10. Restart each of the previously Running endpoints by
 1018 * ringing their doorbells.'
 1019 */
 1020 for (i = 0; i < sc->sc_maxslots; i++) {
 1021 struct xhci_slot *xs = &sc->sc_slots[i];
 1022
 1023 /* Skip if the slot is not in use. */
 1024 if (xs->xs_idx == 0)
 1025 continue;
 1026
 1027 for (dci = XHCI_DCI_SLOT; dci <= XHCI_MAX_DCI; dci++) {
 1028 /* Skip if the endpoint is not Running. */
 1029 if (xhci_get_epstate(sc, xs, dci) !=
 1030 XHCI_EPSTATE_RUNNING)
 1031 continue;
 1032
 1033 /* Ring the doorbell. */
 1034 xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci);
 1035 }
 1036 }
 1037
 1038 /*
 1039 * `Note: After a Save or Restore operation completes, the
 1040 * Save/Restore Error (SRE) flag in the USBSTS register should
 1041 * be checked to ensure that the operation completed
 1042 * successfully.'
 1043 */
 1044 if (xhci_op_read_4(sc, XHCI_USBSTS) & XHCI_STS_SRE) {
 1045 device_printf(self, "resume error, USBSTS.SRE\n");
 1046 return false;
 1047 }
 1048
 1049 return true;
710} 1050}
711 1051
712bool 1052bool
713xhci_shutdown(device_t self, int flags) 1053xhci_shutdown(device_t self, int flags)
714{ 1054{
715 return false; 1055 return false;
716} 1056}
717 1057
718static int 1058static int
719xhci_hc_reset(struct xhci_softc * const sc) 1059xhci_hc_reset(struct xhci_softc * const sc)
720{ 1060{
721 uint32_t usbcmd, usbsts; 1061 uint32_t usbcmd, usbsts;
722 int i; 1062 int i;
@@ -762,27 +1102,26 @@ xhci_hc_reset(struct xhci_softc * const  @@ -762,27 +1102,26 @@ xhci_hc_reset(struct xhci_softc * const
762 if ((usbsts & XHCI_STS_CNR) == 0) 1102 if ((usbsts & XHCI_STS_CNR) == 0)
763 break; 1103 break;
764 usb_delay_ms(&sc->sc_bus, 1); 1104 usb_delay_ms(&sc->sc_bus, 1);
765 } 1105 }
766 if (i >= XHCI_WAIT_CNR) { 1106 if (i >= XHCI_WAIT_CNR) {
767 aprint_error_dev(sc->sc_dev, 1107 aprint_error_dev(sc->sc_dev,
768 "controller not ready timeout after reset\n"); 1108 "controller not ready timeout after reset\n");
769 return EIO; 1109 return EIO;
770 } 1110 }
771 1111
772 return 0; 1112 return 0;
773} 1113}
774 1114
775 
776/* 7.2 xHCI Support Protocol Capability */ 1115/* 7.2 xHCI Support Protocol Capability */
777static void 1116static void
778xhci_id_protocols(struct xhci_softc *sc, bus_size_t ecp) 1117xhci_id_protocols(struct xhci_softc *sc, bus_size_t ecp)
779{ 1118{
780 XHCIHIST_FUNC(); XHCIHIST_CALLED(); 1119 XHCIHIST_FUNC(); XHCIHIST_CALLED();
781 1120
782 /* XXX Cache this lot */ 1121 /* XXX Cache this lot */
783 1122
784 const uint32_t w0 = xhci_read_4(sc, ecp); 1123 const uint32_t w0 = xhci_read_4(sc, ecp);
785 const uint32_t w4 = xhci_read_4(sc, ecp + 4); 1124 const uint32_t w4 = xhci_read_4(sc, ecp + 4);
786 const uint32_t w8 = xhci_read_4(sc, ecp + 8); 1125 const uint32_t w8 = xhci_read_4(sc, ecp + 8);
787 const uint32_t wc = xhci_read_4(sc, ecp + 0xc); 1126 const uint32_t wc = xhci_read_4(sc, ecp + 0xc);
788 1127

cvs diff -r1.18 -r1.19 src/sys/dev/usb/xhcireg.h (expand / switch to unified diff)

--- src/sys/dev/usb/xhcireg.h 2020/06/06 08:56:30 1.18
+++ src/sys/dev/usb/xhcireg.h 2021/05/23 11:49:45 1.19
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xhcireg.h,v 1.18 2020/06/06 08:56:30 skrll Exp $ */ 1/* $NetBSD: xhcireg.h,v 1.19 2021/05/23 11:49:45 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved. 4 * Copyright (c) 2010 Hans Petter Selasky. All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 14 *
@@ -122,26 +122,30 @@ @@ -122,26 +122,30 @@
122#define XHCI_CMD_HSEE __BIT(3) /* RW Host System Error Enable */ 122#define XHCI_CMD_HSEE __BIT(3) /* RW Host System Error Enable */
123#define XHCI_CMD_LHCRST __BIT(7) /* RO/RW Light Host Controller Reset */ 123#define XHCI_CMD_LHCRST __BIT(7) /* RO/RW Light Host Controller Reset */
124#define XHCI_CMD_CSS __BIT(8) /* RW Controller Save State */ 124#define XHCI_CMD_CSS __BIT(8) /* RW Controller Save State */
125#define XHCI_CMD_CRS __BIT(9) /* RW Controller Restore State */ 125#define XHCI_CMD_CRS __BIT(9) /* RW Controller Restore State */
126#define XHCI_CMD_EWE __BIT(10) /* RW Enable Wrap Event */ 126#define XHCI_CMD_EWE __BIT(10) /* RW Enable Wrap Event */
127#define XHCI_CMD_EU3S __BIT(11) /* RW Enable U3 MFINDEX Stop */ 127#define XHCI_CMD_EU3S __BIT(11) /* RW Enable U3 MFINDEX Stop */
128#define XHCI_CMD_CME __BIT(13) /* RW CEM Enable */ 128#define XHCI_CMD_CME __BIT(13) /* RW CEM Enable */
129#define XHCI_CMD_ETE __BIT(14) /* RW Extended TBC Enable */ 129#define XHCI_CMD_ETE __BIT(14) /* RW Extended TBC Enable */
130#define XHCI_CMD_TSC_EN __BIT(15) /* RW Extended TBC TRB Status Enable */ 130#define XHCI_CMD_TSC_EN __BIT(15) /* RW Extended TBC TRB Status Enable */
131#define XHCI_CMD_VTIOE __BIT(16) /* RW VTIO Enable */ 131#define XHCI_CMD_VTIOE __BIT(16) /* RW VTIO Enable */
132 132
133#define XHCI_WAIT_CNR 100 /* in 1ms */ 133#define XHCI_WAIT_CNR 100 /* in 1ms */
134#define XHCI_WAIT_HCRST 100 /* in 1ms */ 134#define XHCI_WAIT_HCRST 100 /* in 1ms */
 135#define XHCI_WAIT_RSS 100 /* in 1ms */
 136#define XHCI_WAIT_SSS 100 /* in 1ms */
 137#define XHCI_WAIT_PLS_U0 100 /* in 1ms */
 138#define XHCI_WAIT_PLS_U3 10 /* in 1ms */
135 139
136#define XHCI_USBSTS 0x04 /* XHCI status */ 140#define XHCI_USBSTS 0x04 /* XHCI status */
137#define XHCI_STS_HCH __BIT(0) /* RO - Host Controller Halted */ 141#define XHCI_STS_HCH __BIT(0) /* RO - Host Controller Halted */
138#define XHCI_STS_RSVDZ0 __BIT(1) /* RsvdZ - 1:1 */ 142#define XHCI_STS_RSVDZ0 __BIT(1) /* RsvdZ - 1:1 */
139#define XHCI_STS_HSE __BIT(2) /* RW - Host System Error */ 143#define XHCI_STS_HSE __BIT(2) /* RW - Host System Error */
140#define XHCI_STS_EINT __BIT(3) /* RW - Event Interrupt */ 144#define XHCI_STS_EINT __BIT(3) /* RW - Event Interrupt */
141#define XHCI_STS_PCD __BIT(4) /* RW - Port Change Detect */ 145#define XHCI_STS_PCD __BIT(4) /* RW - Port Change Detect */
142#define XHCI_STS_RSVDZ1 __BITS(7, 5) /* RsvdZ - 7:5 */ 146#define XHCI_STS_RSVDZ1 __BITS(7, 5) /* RsvdZ - 7:5 */
143#define XHCI_STS_SSS __BIT(8) /* RO - Save State Status */ 147#define XHCI_STS_SSS __BIT(8) /* RO - Save State Status */
144#define XHCI_STS_RSS __BIT(9) /* RO - Restore State Status */ 148#define XHCI_STS_RSS __BIT(9) /* RO - Restore State Status */
145#define XHCI_STS_SRE __BIT(10) /* RW - Save/Restore Error */ 149#define XHCI_STS_SRE __BIT(10) /* RW - Save/Restore Error */
146#define XHCI_STS_CNR __BIT(11) /* RO - Controller Not Ready */ 150#define XHCI_STS_CNR __BIT(11) /* RO - Controller Not Ready */
147#define XHCI_STS_HCE __BIT(12) /* RO - Host Controller Error */ 151#define XHCI_STS_HCE __BIT(12) /* RO - Host Controller Error */

cvs diff -r1.17 -r1.18 src/sys/dev/usb/xhcivar.h (expand / switch to unified diff)

--- src/sys/dev/usb/xhcivar.h 2020/08/21 20:46:03 1.17
+++ src/sys/dev/usb/xhcivar.h 2021/05/23 11:49:45 1.18
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: xhcivar.h,v 1.17 2020/08/21 20:46:03 jakllsch Exp $ */ 1/* $NetBSD: xhcivar.h,v 1.18 2021/05/23 11:49:45 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2013 Jonathan A. Kollasch 4 * Copyright (c) 2013 Jonathan A. Kollasch
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -127,26 +127,38 @@ struct xhci_softc { @@ -127,26 +127,38 @@ struct xhci_softc {
127 struct xhci_soft_trb sc_result_trb; 127 struct xhci_soft_trb sc_result_trb;
128 bool sc_resultpending; 128 bool sc_resultpending;
129 129
130 bool sc_dying; 130 bool sc_dying;
131 131
132 void (*sc_vendor_init)(struct xhci_softc *); 132 void (*sc_vendor_init)(struct xhci_softc *);
133 int (*sc_vendor_port_status)(struct xhci_softc *, uint32_t, int); 133 int (*sc_vendor_port_status)(struct xhci_softc *, uint32_t, int);
134 134
135 int sc_quirks; 135 int sc_quirks;
136#define XHCI_QUIRK_INTEL __BIT(0) /* Intel xhci chip */ 136#define XHCI_QUIRK_INTEL __BIT(0) /* Intel xhci chip */
137#define XHCI_DEFERRED_START __BIT(1) 137#define XHCI_DEFERRED_START __BIT(1)
138 uint32_t sc_hcc; /* copy of HCCPARAMS1 */ 138 uint32_t sc_hcc; /* copy of HCCPARAMS1 */
139 uint32_t sc_hcc2; /* copy of HCCPARAMS2 */ 139 uint32_t sc_hcc2; /* copy of HCCPARAMS2 */
 140
 141 struct xhci_registers {
 142 uint32_t usbcmd;
 143 uint32_t dnctrl;
 144 uint64_t dcbaap;
 145 uint32_t config;
 146 uint32_t erstsz0;
 147 uint64_t erstba0;
 148 uint64_t erdp0;
 149 uint32_t iman0;
 150 uint32_t imod0;
 151 } sc_regs;
140}; 152};
141 153
142int xhci_init(struct xhci_softc *); 154int xhci_init(struct xhci_softc *);
143void xhci_start(struct xhci_softc *); 155void xhci_start(struct xhci_softc *);
144int xhci_intr(void *); 156int xhci_intr(void *);
145int xhci_detach(struct xhci_softc *, int); 157int xhci_detach(struct xhci_softc *, int);
146int xhci_activate(device_t, enum devact); 158int xhci_activate(device_t, enum devact);
147void xhci_childdet(device_t, device_t); 159void xhci_childdet(device_t, device_t);
148bool xhci_suspend(device_t, const pmf_qual_t *); 160bool xhci_suspend(device_t, const pmf_qual_t *);
149bool xhci_resume(device_t, const pmf_qual_t *); 161bool xhci_resume(device_t, const pmf_qual_t *);
150bool xhci_shutdown(device_t, int); 162bool xhci_shutdown(device_t, int);
151 163
152#define XHCI_TRANSFER_RING_TRBS 256 164#define XHCI_TRANSFER_RING_TRBS 256