From 4a2c762c3058d33cade55bdb5c60f9d6b40d7198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20MONTHOU=C3=8BL?= Date: Thu, 30 Nov 2017 10:36:39 +0100 Subject: [PATCH] 8870 do not lock cpu when waiting for IBF or OBF commit 8ad8a2c4a4abef9af95f1033b18eecffe4860896 Author: jhb Date: Mon Dec 22 16:53:04 2014 +0000 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 --- usr/src/uts/intel/io/ipmi/ipmi_kcs.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/usr/src/uts/intel/io/ipmi/ipmi_kcs.c b/usr/src/uts/intel/io/ipmi/ipmi_kcs.c index 08302639b814..9e5c786d61fc 100644 --- a/usr/src/uts/intel/io/ipmi/ipmi_kcs.c +++ b/usr/src/uts/intel/io/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(drv_usectohz(1000000)); @@ -222,6 +227,8 @@ kcs_write_byte(struct ipmi_softc *sc, uchar_t 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, uchar_t 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 */ @@ -273,6 +282,8 @@ kcs_read_byte(struct ipmi_softc *sc, uchar_t *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); @@ -287,6 +298,8 @@ kcs_read_byte(struct ipmi_softc *sc, uchar_t *data) /* Wait for OBF = 1 */ status = kcs_wait_for_obf(sc, 1); + if ((status & KCS_STATUS_OBF) == 0) + return (0); /* Read Dummy */ (void) INB(sc, KCS_DATA);