From 642ac9c9ea3ccc7cc7be340bed53aebe0223b941 Mon Sep 17 00:00:00 2001 From: Peter Kosyh Date: Wed, 10 Oct 2018 09:54:05 +0300 Subject: [PATCH] xhci: GetPortStatus, ClearPortFeature (PS_PLC, PS_WRC) fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #13768. Change-Id: Ia783e62a15917a2c8f7b3169ee5204a8d8d6f5ef Reviewed-on: https://review.haiku-os.org/622 Reviewed-by: Jérôme Duval Reviewed-by: Alexander von Gluck IV --- src/add-ons/kernel/bus_managers/usb/Hub.cpp | 15 +++++++++++++++ .../kernel/bus_managers/usb/usbspec_private.h | 5 ++++- src/add-ons/kernel/busses/usb/xhci.cpp | 10 ++++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/usb/Hub.cpp b/src/add-ons/kernel/bus_managers/usb/Hub.cpp index 64bc4516f0..f06712d1de 100644 --- a/src/add-ons/kernel/bus_managers/usb/Hub.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Hub.cpp @@ -335,6 +335,21 @@ Hub::Explore(change_item **changeList) USB_REQUEST_CLEAR_FEATURE, C_PORT_RESET, i + 1, 0, NULL, 0, NULL); } + + if (fPortStatus[i].change & PORT_CHANGE_LINK_STATE) { + TRACE_ALWAYS("port %" B_PRId32 " link state changed\n", i); + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + USB_REQUEST_CLEAR_FEATURE, C_PORT_LINK_STATE, i + 1, + 0, NULL, 0, NULL); + } + + if (fPortStatus[i].change & PORT_CHANGE_BH_PORT_RESET) { + TRACE_ALWAYS("port %" B_PRId32 " was warm reset\n", i); + DefaultPipe()->SendRequest(USB_REQTYPE_CLASS | USB_REQTYPE_OTHER_OUT, + USB_REQUEST_CLEAR_FEATURE, C_PORT_BH_PORT_RESET, i + 1, + 0, NULL, 0, NULL); + } + } // explore down the tree if we have hubs connected diff --git a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h index 8123389e8a..c9ca3686b7 100644 --- a/src/add-ons/kernel/bus_managers/usb/usbspec_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usbspec_private.h @@ -102,7 +102,7 @@ struct usb_port_status #define PORT_STATUS_HIGH_SPEED 0x0400 #define PORT_STATUS_TEST 0x0800 #define PORT_STATUS_INDICATOR 0x1000 -// USB 3.0 spec table 10-11 +// USB 3.0 spec table 10-10 #define PORT_STATUS_SS_LINK_STATE 0x01e0 #define PORT_STATUS_SS_POWER 0x0200 #define PORT_STATUS_SS_SPEED 0x1c00 @@ -135,5 +135,8 @@ struct usb_port_status #define C_PORT_BH_PORT_RESET 29 #define PORT_FORCE_LINKPM_STATE 30 +// USB 3.0 spec table 10-11 +#define PORT_CHANGE_BH_PORT_RESET 0x0020 +#define PORT_CHANGE_LINK_STATE 0x0040 #endif // _USBSPEC_PRIVATE_H diff --git a/src/add-ons/kernel/busses/usb/xhci.cpp b/src/add-ons/kernel/busses/usb/xhci.cpp index b70b51c4fb..ea81660619 100644 --- a/src/add-ons/kernel/busses/usb/xhci.cpp +++ b/src/add-ons/kernel/busses/usb/xhci.cpp @@ -1789,9 +1789,9 @@ XHCI::GetPortStatus(uint8 index, usb_port_status* status) if (fPortSpeeds[index] == USB_SPEED_SUPER) { if (portStatus & PS_PLC) - status->change |= PORT_LINK_STATE; + status->change |= PORT_CHANGE_LINK_STATE; if (portStatus & PS_WRC) - status->change |= PORT_BH_PORT_RESET; + status->change |= PORT_CHANGE_BH_PORT_RESET; } return B_OK; @@ -1874,6 +1874,12 @@ XHCI::ClearPortFeature(uint8 index, uint16 feature) case C_PORT_RESET: WriteOpReg(portRegister, portStatus | PS_PRC); break; + case C_PORT_BH_PORT_RESET: + WriteOpReg(portRegister, portStatus | PS_WRC); + break; + case C_PORT_LINK_STATE: + WriteOpReg(portRegister, portStatus | PS_PLC); + break; default: return B_BAD_VALUE; }