diff options
author | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2009-09-18 15:50:56 +0000 |
---|---|---|
committer | Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net> | 2009-09-18 15:50:56 +0000 |
commit | 3aa8596699cfb0587aecc5f2e778cdaf844b1b2b (patch) | |
tree | ef1a254b134a43ccae502cffca6aa08b994a3998 /ichspi.c | |
parent | 8d42c2ebc8300643303bb7ab88b8fe0b7c0cd4af (diff) | |
download | flashrom-3aa8596699cfb0587aecc5f2e778cdaf844b1b2b.zip flashrom-3aa8596699cfb0587aecc5f2e778cdaf844b1b2b.tar.gz |
The current ICH SPI preop handling is a hack which spews lots of warnings, but still yields correct results
With the multicommand infrastructure I introduced in r645, it became possible
to integrate ICH SPI preopcodes cleanly into the flashrom design. The new
code checks for every opcode in a multicommand array if it is a preopcode.
If yes, it checks if the next opcode is associated with that preopcode and
in that case it simply runs the opcode because the correct preopcode will be
run automatically before the opcode.
Corresponding to flashrom svn r727.
Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: FENG Yu Ning <fengyuning1984@gmail.com>
Diffstat (limited to 'ichspi.c')
-rw-r--r-- | ichspi.c | 35 |
1 files changed, 21 insertions, 14 deletions
@@ -742,22 +742,29 @@ int ich_spi_send_command(unsigned int writecnt, unsigned int readcnt, return result; } -int ich_spi_send_multicommand(struct spi_command *spicommands) +int ich_spi_send_multicommand(struct spi_command *cmds) { int ret = 0; - while ((spicommands->writecnt || spicommands->readcnt) && !ret) { - ret = ich_spi_send_command(spicommands->writecnt, spicommands->readcnt, - spicommands->writearr, spicommands->readarr); - /* This awful hack needs to be smarter. - */ - if ((ret == SPI_INVALID_OPCODE) && - ((spicommands->writearr[0] == JEDEC_WREN) || - (spicommands->writearr[0] == JEDEC_EWSR))) { - printf_debug(" due to SPI master limitation, ignoring" - " and hoping it will be run as PREOP\n"); - ret = 0; - } - spicommands++; + int oppos, preoppos; + for (; (cmds->writecnt || cmds->readcnt) && !ret; cmds++) { + /* Is the next command valid or a terminator? */ + if ((cmds + 1)->writecnt || (cmds + 1)->readcnt) { + preoppos = find_preop(curopcodes, cmds->writearr[0]); + oppos = find_opcode(curopcodes, (cmds + 1)->writearr[0]); + /* Is the opcode of the current command listed in the + * ICH struct OPCODES as associated preopcode for the + * opcode of the next command? + */ + if ((oppos != -1) && (preoppos != -1) && + (curopcodes->opcode[oppos].atomic - 1 == preoppos)) { + printf_debug("opcode 0x%02x will be run as PREOP\n", + cmds->writearr[0]); + continue; + } + } + + ret = ich_spi_send_command(cmds->writecnt, cmds->readcnt, + cmds->writearr, cmds->readarr); } return ret; } |