Author: hselasky
Date: Wed Oct 26 17:43:27 2011
New Revision: 226803
URL: http://svn.freebsd.org/changeset/base/226803

Log:
  Fix suspend and resume of FULL and HIGH speed USB devices
  in the generic XHCI driver. There appears to be some minor
  logic missing for this feature to work.
  
  MFC after:    3 days

Modified:
  head/sys/dev/usb/controller/xhci.c
  head/sys/dev/usb/controller/xhcireg.h
  head/sys/dev/usb/usb.h
  head/sys/dev/usb/usb_hub.c

Modified: head/sys/dev/usb/controller/xhci.c
==============================================================================
--- head/sys/dev/usb/controller/xhci.c  Wed Oct 26 17:26:38 2011        
(r226802)
+++ head/sys/dev/usb/controller/xhci.c  Wed Oct 26 17:43:27 2011        
(r226803)
@@ -3048,7 +3048,9 @@ xhci_roothub_exec(struct usb_device *ude
                }
                port = XHCI_PORTSC(index);
 
-               v = XREAD4(sc, oper, port) & ~XHCI_PS_CLEAR;
+               v = XREAD4(sc, oper, port);
+               i = XHCI_PS_PLS_GET(v);
+               v &= ~XHCI_PS_CLEAR;
 
                switch (value) {
                case UHF_C_BH_PORT_RESET:
@@ -3082,6 +3084,17 @@ xhci_roothub_exec(struct usb_device *ude
                        XWRITE4(sc, oper, port, v & ~XHCI_PS_PIC_SET(3));
                        break;
                case UHF_PORT_SUSPEND:
+
+                       /* U3 -> U15 */
+                       if (i == 3) {
+                               XWRITE4(sc, oper, port, v |
+                                   XHCI_PS_PLS_SET(0xF) | XHCI_PS_LWS);
+                       }
+
+                       /* wait 20ms for resume sequence to complete */
+                       usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 50);
+
+                       /* U0 */
                        XWRITE4(sc, oper, port, v |
                            XHCI_PS_PLS_SET(0) | XHCI_PS_LWS);
                        break;

Modified: head/sys/dev/usb/controller/xhcireg.h
==============================================================================
--- head/sys/dev/usb/controller/xhcireg.h       Wed Oct 26 17:26:38 2011        
(r226802)
+++ head/sys/dev/usb/controller/xhcireg.h       Wed Oct 26 17:43:27 2011        
(r226803)
@@ -133,7 +133,7 @@
 #define        XHCI_PS_WOE             0x08000000      /* RW - wake on 
over-current enable */
 #define        XHCI_PS_DR              0x40000000      /* RO - device 
removable */
 #define        XHCI_PS_WPR             0x80000000U     /* RW - warm port reset 
*/
-#define        XHCI_PS_CLEAR           0x80FF00F7U     /* command bits */
+#define        XHCI_PS_CLEAR           0x80FF01FFU     /* command bits */
 
 #define        XHCI_PORTPMSC(n)        (0x3F4 + (0x10 * (n)))  /* XHCI status 
and control */
 #define        XHCI_PM3_U1TO_GET(x)    (((x) >> 0) & 0xFF)     /* RW - U1 
timeout */

Modified: head/sys/dev/usb/usb.h
==============================================================================
--- head/sys/dev/usb/usb.h      Wed Oct 26 17:26:38 2011        (r226802)
+++ head/sys/dev/usb/usb.h      Wed Oct 26 17:43:27 2011        (r226803)
@@ -686,6 +686,7 @@ struct usb_port_status {
 #define        UPS_PORT_LS_HOT_RST     0x09
 #define        UPS_PORT_LS_COMP_MODE   0x0A
 #define        UPS_PORT_LS_LOOPBACK    0x0B
+#define        UPS_PORT_LS_RESUME      0x0F
 #define        UPS_PORT_POWER                  0x0100
 #define        UPS_LOW_SPEED                   0x0200
 #define        UPS_HIGH_SPEED                  0x0400

Modified: head/sys/dev/usb/usb_hub.c
==============================================================================
--- head/sys/dev/usb/usb_hub.c  Wed Oct 26 17:26:38 2011        (r226802)
+++ head/sys/dev/usb/usb_hub.c  Wed Oct 26 17:43:27 2011        (r226803)
@@ -611,6 +611,7 @@ uhub_suspend_resume_port(struct uhub_sof
                switch (UPS_PORT_LINK_STATE_GET(sc->sc_st.port_status)) {
                case UPS_PORT_LS_U0:
                case UPS_PORT_LS_U1:
+               case UPS_PORT_LS_RESUME:
                        is_suspend = 0;
                        break;
                default:
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to