Commit 15c7c6b31ad8742bd6e63be35f82193895ff8bdd
Committed by
Simon Glass
1 parent
a5a5882611
Exists in
v2017.01-smarct4x
and in
37 other branches
x86: ich-spi: Fix a bug of reading from a non-64 bytes aligned address
The ich spi controller driver spi_xfer() tries to align reading address to 64 bytes when doing spi data in, which causes a bug of either infinite loop or a huge size memcpy(). Actually the ich spi controller does not have such requirement of 64 bytes alignment when reading data from spi slave devices. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Simon Glass <sjg@chromium.org> Tested-by: Simon Glass <sjg@chromium.org>
Showing 1 changed file with 2 additions and 15 deletions Side-by-side Diff
drivers/spi/ich.c
... | ... | @@ -483,8 +483,6 @@ |
483 | 483 | struct spi_trans *trans = &ich->trans; |
484 | 484 | unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END); |
485 | 485 | int using_cmd = 0; |
486 | - /* Align read transactions to 64-byte boundaries */ | |
487 | - char buff[ctlr.databytes]; | |
488 | 486 | |
489 | 487 | /* Ee don't support writing partial bytes. */ |
490 | 488 | if (bitlen % 8) { |
491 | 489 | |
492 | 490 | |
... | ... | @@ -632,14 +630,9 @@ |
632 | 630 | */ |
633 | 631 | while (trans->bytesout || trans->bytesin) { |
634 | 632 | uint32_t data_length; |
635 | - uint32_t aligned_offset; | |
636 | - uint32_t diff; | |
637 | 633 | |
638 | - aligned_offset = trans->offset & ~(ctlr.databytes - 1); | |
639 | - diff = trans->offset - aligned_offset; | |
640 | - | |
641 | 634 | /* SPI addresses are 24 bit only */ |
642 | - ich_writel(aligned_offset & 0x00FFFFFF, ctlr.addr); | |
635 | + ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr); | |
643 | 636 | |
644 | 637 | if (trans->bytesout) |
645 | 638 | data_length = min(trans->bytesout, ctlr.databytes); |
... | ... | @@ -673,13 +666,7 @@ |
673 | 666 | } |
674 | 667 | |
675 | 668 | if (trans->bytesin) { |
676 | - if (diff) { | |
677 | - data_length -= diff; | |
678 | - read_reg(ctlr.data, buff, ctlr.databytes); | |
679 | - memcpy(trans->in, buff + diff, data_length); | |
680 | - } else { | |
681 | - read_reg(ctlr.data, trans->in, data_length); | |
682 | - } | |
669 | + read_reg(ctlr.data, trans->in, data_length); | |
683 | 670 | spi_use_in(trans, data_length); |
684 | 671 | if (with_address) |
685 | 672 | trans->offset += data_length; |