diff options
author | jhb <jhb@FreeBSD.org> | 2015-02-06 18:41:57 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2015-02-06 18:41:57 +0000 |
commit | 865011c5e604137e7c256c0958006602a9d5dcbc (patch) | |
tree | 0b33c087de0cbd2d1d97a63bb6601488f729d45d | |
parent | 1fa38dee26fb14059a2b4fa98625a6d7f8879924 (diff) | |
download | FreeBSD-src-865011c5e604137e7c256c0958006602a9d5dcbc.zip FreeBSD-src-865011c5e604137e7c256c0958006602a9d5dcbc.tar.gz |
MFC 276065:
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.
-rw-r--r-- | sys/dev/ipmi/ipmi_kcs.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/sys/dev/ipmi/ipmi_kcs.c b/sys/dev/ipmi/ipmi_kcs.c index 76adf8c..eb5884a 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); |