summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeng Xu <pengxu@google.com>2016-07-12 12:00:21 -0700
committergitbuildkicker <android-build@google.com>2016-07-21 16:17:25 -0700
commit2f784aec07f9932f25a1915e0390ed59b1a4cfe6 (patch)
tree9ea59e75621089465279d14c437816c01436d16d
parent3d66dd43bec0e95c0bcd55372d18aee2b908ce17 (diff)
downloadcontexthub-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.c16
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