Commit 15c7c6b31ad8742bd6e63be35f82193895ff8bdd

Authored by Bin Meng
Committed by Simon Glass
1 parent a5a5882611

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

... ... @@ -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;