svn commit: r359319 - stable/9/sys/dev/usb
Hans Petter Selasky
hselasky at FreeBSD.org
Thu Mar 26 05:39:29 UTC 2020
Author: hselasky
Date: Thu Mar 26 05:39:20 2020
New Revision: 359319
URL: https://svnweb.freebsd.org/changeset/base/359319
Log:
MFC r359120:
Correctly implement support for remote wakeup for USB 3.0 device.
Submitted by: Horse Ma <Shichun.Ma at dell.com>
Sponsored by: Mellanox Technologies
Modified:
stable/9/sys/dev/usb/usb.h
stable/9/sys/dev/usb/usb_hub.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/dev/usb/usb.h
==============================================================================
--- stable/9/sys/dev/usb/usb.h Thu Mar 26 05:38:33 2020 (r359318)
+++ stable/9/sys/dev/usb/usb.h Thu Mar 26 05:39:20 2020 (r359319)
@@ -267,6 +267,11 @@ typedef struct usb_device_request usb_device_request_t
#define UHF_C_BH_PORT_RESET 29
#define UHF_FORCE_LINKPM_ACCEPT 30
+/* SuperSpeed suspend support */
+#define USB_INTERFACE_FUNC_SUSPEND 0
+#define USB_INTERFACE_FUNC_SUSPEND_LP (1 << 8)
+#define USB_INTERFACE_FUNC_SUSPEND_RW (1 << 9)
+
struct usb_descriptor {
uByte bLength;
uByte bDescriptorType;
Modified: stable/9/sys/dev/usb/usb_hub.c
==============================================================================
--- stable/9/sys/dev/usb/usb_hub.c Thu Mar 26 05:38:33 2020 (r359318)
+++ stable/9/sys/dev/usb/usb_hub.c Thu Mar 26 05:39:20 2020 (r359319)
@@ -2483,6 +2483,50 @@ usb_bus_powerd(struct usb_bus *bus)
}
#endif
+static usb_error_t
+usbd_device_30_remote_wakeup(struct usb_device *udev, uint8_t bRequest)
+{
+ struct usb_device_request req = {};
+
+ req.bmRequestType = UT_WRITE_INTERFACE;
+ req.bRequest = bRequest;
+ USETW(req.wValue, USB_INTERFACE_FUNC_SUSPEND);
+ USETW(req.wIndex, USB_INTERFACE_FUNC_SUSPEND_LP |
+ USB_INTERFACE_FUNC_SUSPEND_RW);
+
+ return (usbd_do_request(udev, NULL, &req, 0));
+}
+
+static usb_error_t
+usbd_clear_dev_wakeup(struct usb_device *udev)
+{
+ usb_error_t err;
+
+ if (usb_device_20_compatible(udev)) {
+ err = usbd_req_clear_device_feature(udev,
+ NULL, UF_DEVICE_REMOTE_WAKEUP);
+ } else {
+ err = usbd_device_30_remote_wakeup(udev,
+ UR_CLEAR_FEATURE);
+ }
+ return (err);
+}
+
+static usb_error_t
+usbd_set_dev_wakeup(struct usb_device *udev)
+{
+ usb_error_t err;
+
+ if (usb_device_20_compatible(udev)) {
+ err = usbd_req_set_device_feature(udev,
+ NULL, UF_DEVICE_REMOTE_WAKEUP);
+ } else {
+ err = usbd_device_30_remote_wakeup(udev,
+ UR_SET_FEATURE);
+ }
+ return (err);
+}
+
/*------------------------------------------------------------------------*
* usb_dev_resume_peer
*
@@ -2586,8 +2630,7 @@ usb_dev_resume_peer(struct usb_device *udev)
/* check if peer has wakeup capability */
if (usb_peer_can_wakeup(udev)) {
/* clear remote wakeup */
- err = usbd_req_clear_device_feature(udev,
- NULL, UF_DEVICE_REMOTE_WAKEUP);
+ err = usbd_clear_dev_wakeup(udev);
if (err) {
DPRINTFN(0, "Clearing device "
"remote wakeup failed: %s\n",
@@ -2652,8 +2695,7 @@ repeat:
*/
/* allow device to do remote wakeup */
- err = usbd_req_set_device_feature(udev,
- NULL, UF_DEVICE_REMOTE_WAKEUP);
+ err = usbd_set_dev_wakeup(udev);
if (err) {
DPRINTFN(0, "Setting device "
"remote wakeup failed\n");
@@ -2679,8 +2721,7 @@ repeat:
if (err != 0) {
if (usb_peer_can_wakeup(udev)) {
/* allow device to do remote wakeup */
- err = usbd_req_clear_device_feature(udev,
- NULL, UF_DEVICE_REMOTE_WAKEUP);
+ err = usbd_clear_dev_wakeup(udev);
if (err) {
DPRINTFN(0, "Setting device "
"remote wakeup failed\n");
More information about the svn-src-stable-9
mailing list