summaryrefslogtreecommitdiff
path: root/payloads/libpayload/drivers
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2013-09-03 16:44:15 -0700
committerIsaac Christensen <isaac.christensen@se-eng.com>2014-08-12 23:19:42 +0200
commit4498f6a6e57aa3bc1ed9449e3ad153b1a60c4eb6 (patch)
treeae5d300ddadec7a73aef4a3a3f39ad05fd7b70d8 /payloads/libpayload/drivers
parenteb623ab2044f77648658f4b0763616f5e1bea57a (diff)
downloadcoreboot-4498f6a6e57aa3bc1ed9449e3ad153b1a60c4eb6.tar.xz
libpayload: usbhub: Don't clear PSC unless it was set
The current USB hub code always clears the port status change after checking it, regardless of whether it was set in the first place. Since this check runs on every poll, it might create a race condition where the port status changes right between the GET_PORT_STATUS and the CLEAR_FEATURE(C_PORT_CONNECT), thus clearing the statrus change flag before it was ever read. Let's add one extra if() to avoid that possible headache. Change-Id: Idd46c2199dc6c240bd9ef068fbe70cccc88bac42 Signed-off-by: Julius Werner <jwerner@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/168098 (cherry picked from commit f7f6f008f701ab3e4a4f785032d8024d676e11cb) Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Reviewed-on: http://review.coreboot.org/6617 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'payloads/libpayload/drivers')
-rw-r--r--payloads/libpayload/drivers/usb/usbhub.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/payloads/libpayload/drivers/usb/usbhub.c b/payloads/libpayload/drivers/usb/usbhub.c
index 4e077f6848..ff7904cbd0 100644
--- a/payloads/libpayload/drivers/usb/usbhub.c
+++ b/payloads/libpayload/drivers/usb/usbhub.c
@@ -48,7 +48,8 @@ usb_hub_port_status_changed(usbdev_t *const dev, const int port)
{
unsigned short buf[2] = { 0, 0 };
get_status (dev, port, DR_PORT, 4, buf);
- clear_feature (dev, port, SEL_C_PORT_CONNECTION, DR_PORT);
+ if (buf[1] & PORT_CONNECTION)
+ clear_feature (dev, port, SEL_C_PORT_CONNECTION, DR_PORT);
return buf[1] & PORT_CONNECTION;
}