diff options
author | Peng Xu <pengxu@google.com> | 2016-07-12 12:00:21 -0700 |
---|---|---|
committer | gitbuildkicker <android-build@google.com> | 2016-07-21 16:17:25 -0700 |
commit | 2f784aec07f9932f25a1915e0390ed59b1a4cfe6 (patch) | |
tree | 9ea59e75621089465279d14c437816c01436d16d | |
parent | 3d66dd43bec0e95c0bcd55372d18aee2b908ce17 (diff) | |
download | contexthub-2f784aec07f9932f25a1915e0390ed59b1a4cfe6.tar.gz |
BMI160 SPI op queue race condition fix
The async SPI queue index is reset after a SPI command is sent to
SPI driver. However, if the SPI transaction is very short and there
is other interrupts going on, the SPI driver can finish and invoke
SPI transaction callback before the reset happen. If the callback
tries to send another SPI command, the new command will be appended
after previous one and cause problem.
This CL fix this issue by saving a copy of the index before calling
SPI driver and thus avoid the problem.
cherry-pick from fb5ffc3b774fc87b3dcf70261188393eef81423a
bug: b/29625330
Change-Id: I509ab9449b6718e2277f6ae5ab29112cbf0a3496
-rw-r--r-- | firmware/src/drivers/bosch_bmi160/bosch_bmi160.c | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/firmware/src/drivers/bosch_bmi160/bosch_bmi160.c b/firmware/src/drivers/bosch_bmi160/bosch_bmi160.c index d682af0a..9d067b1d 100644 --- a/firmware/src/drivers/bosch_bmi160/bosch_bmi160.c +++ b/firmware/src/drivers/bosch_bmi160/bosch_bmi160.c @@ -687,9 +687,16 @@ static void spiBatchTxRx(struct SpiMode *mode, } T(spiInUse) = true; - spiMasterRxTx(T(spiDev), T(cs), T(packets), T(mRegCnt), mode, callback, cookie); + + // Reset variables before issuing SPI transaction. + // SPI may finish before spiMasterRxTx finish + uint8_t regCount = T(mRegCnt); T(mRegCnt) = 0; T(mWbufCnt) = 0; + + if (spiMasterRxTx(T(spiDev), T(cs), T(packets), regCount, mode, callback, cookie) < 0) { + ERROR_PRINT("spiMasterRxTx failed!\n"); + } } @@ -3198,6 +3205,13 @@ static void chunkedReadInit_(TASK, int index, int size) { return; } + if (T(mRegCnt)) { + //chunked read are always executed as a single command. This should never happen. + ERROR_PRINT("SPI queue not empty at chunkedReadInit, regcnt = %d", T(mRegCnt)); + // In case it did happen, we do not want to write crap to BMI160. + T(mRegCnt) = 0; + } + T(mWbufCnt) = index; if (T(mWbufCnt) > FIFO_READ_SIZE) { // drop data to prevent bigger issue |