aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ipmi
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2014-12-22 16:53:04 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2014-12-22 16:53:04 +0000
commit51f2504057c8a39b3ea244b777d66ea00a391701 (patch)
tree6acf60d0e4fee90b01151c6065fae0beb3af336c /sys/dev/ipmi
parentacb332a8a188196ac0cdfef9598a15000f15b940 (diff)
Explicitly treat timeouts when waiting for IBF or OBF to change state as an
error. This fixes occasional hangs in the IPMI kcs thread when using ipmitool locally. MFC after: 1 week
Notes
svn path=/head/; revision=276065
Diffstat (limited to 'sys/dev/ipmi')
-rw-r--r--sys/dev/ipmi/ipmi_kcs.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/sys/dev/ipmi/ipmi_kcs.c b/sys/dev/ipmi/ipmi_kcs.c
index 76adf8c93098..eb5884a86b57 100644
--- a/sys/dev/ipmi/ipmi_kcs.c
+++ b/sys/dev/ipmi/ipmi_kcs.c
@@ -184,6 +184,8 @@ kcs_start_write(struct ipmi_softc *sc)
for (retry = 0; retry < 10; retry++) {
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
/* Clear OBF */
kcs_clear_obf(sc, status);
@@ -193,6 +195,9 @@ kcs_start_write(struct ipmi_softc *sc)
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
+
if (KCS_STATUS_STATE(status) == KCS_STATUS_STATE_WRITE)
break;
DELAY(1000000);
@@ -222,6 +227,8 @@ kcs_write_byte(struct ipmi_softc *sc, u_char data)
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
return (0);
@@ -244,6 +251,8 @@ kcs_write_last_byte(struct ipmi_softc *sc, u_char data)
/* Wait for IBF = 0 */
status = kcs_wait_for_ibf(sc, 0);
+ if (status & KCS_STATUS_IBF)
+ return (0);
if (KCS_STATUS_STATE(status) != KCS_STATUS_STATE_WRITE)
/* error state */
@@ -274,6 +283,8 @@ kcs_read_byte(struct ipmi_softc *sc, u_char *data)
/* Wait for OBF = 1 */
status = kcs_wait_for_obf(sc, 1);
+ if ((status & KCS_STATUS_OBF) == 0)
+ return (0);
/* Read Data_out */
*data = INB(sc, KCS_DATA);
@@ -288,6 +299,8 @@ kcs_read_byte(struct ipmi_softc *sc, u_char *data)
/* Wait for OBF = 1*/
status = kcs_wait_for_obf(sc, 1);
+ if ((status & KCS_STATUS_OBF) == 0)
+ return (0);
/* Read Dummy */
dummy = INB(sc, KCS_DATA);