summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVic Yang <victoryang@chromium.org>2014-05-20 15:44:58 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-05-21 04:09:37 +0000
commit64e5cc33d99568c665d59040908b6d2452e9983f (patch)
tree7920891460625f0b1571e52758c36c1645d9e9c3
parent951ee9e37944b7f1eea9d9a7921727c663665fd6 (diff)
downloadchrome-ec-64e5cc33d99568c665d59040908b6d2452e9983f.tar.gz
Keyborg: make a copy of response before transmitting
Before transmitting the response back to the master, the slave should make a copy of it. Otherwise, if the buffer is reused, we run the risk of overwriting the last response before it's sent out. We got away with this before because we didn't overwrite it fast enough. Let's fix this to be safe. BUG=None TEST=Build and boot BRANCH=None Change-Id: If3c50692d554119de9ff0f0ae0de450b923b11af Signed-off-by: Vic Yang <victoryang@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/200672 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--board/keyborg/spi_comm.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/board/keyborg/spi_comm.c b/board/keyborg/spi_comm.c
index 8d459d3ae5..f795c3a8f6 100644
--- a/board/keyborg/spi_comm.c
+++ b/board/keyborg/spi_comm.c
@@ -31,7 +31,6 @@ static const struct dma_option dma_rx_option = {
static uint8_t out_msg[SPI_PACKET_MAX_SIZE + 2];
static uint8_t in_msg[SPI_PACKET_MAX_SIZE];
-static uint8_t * const reply_msg = out_msg + 1;
static inline int wait_for_signal(uint32_t port, uint32_t mask,
int value, int timeout_us)
@@ -324,11 +323,14 @@ int spi_slave_send_response_async(struct spi_comm_packet *resp)
if (size > SPI_PACKET_MAX_SIZE)
return EC_ERROR_OVERFLOW;
+ if (out_msg != (uint8_t *)resp)
+ memcpy(out_msg, resp, size);
+
master_slave_sync(100);
if (spi->sr & STM32_SPI_SR_RXNE)
in_msg[0] = spi->dr;
- spi->dr = *((uint8_t *)resp);
+ spi->dr = out_msg[0];
/* Set N_CHG (master SPI_NSS) to high */
STM32_GPIO_BSRR(GPIO_A) = 1 << 1;
@@ -340,7 +342,7 @@ int spi_slave_send_response_async(struct spi_comm_packet *resp)
dma_clear_isr(STM32_DMAC_SPI1_TX);
dma_clear_isr(STM32_DMAC_SPI1_RX);
dma_start_rx(&dma_rx_option, size - 1, in_msg);
- dma_prepare_tx(&dma_tx_option, size - 1, ((uint8_t *)resp)+1);
+ dma_prepare_tx(&dma_tx_option, size - 1, out_msg + 1);
dma_go(dma_get_channel(STM32_DMAC_SPI1_TX));
master_slave_sync(5);
@@ -367,7 +369,7 @@ int spi_slave_send_response_flush(void)
static void spi_slave_nack(void)
{
- struct spi_comm_packet *resp = (struct spi_comm_packet *)reply_msg;
+ struct spi_comm_packet *resp = (struct spi_comm_packet *)out_msg;
resp->cmd_sts = EC_ERROR_UNKNOWN;
resp->size = 0;
@@ -376,7 +378,7 @@ static void spi_slave_nack(void)
static void spi_slave_hello_back(const struct spi_comm_packet *cmd)
{
- struct spi_comm_packet *resp = (struct spi_comm_packet *)reply_msg;
+ struct spi_comm_packet *resp = (struct spi_comm_packet *)out_msg;
uint8_t buf[SPI_PACKET_MAX_SIZE];
int i, sz;