summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2012-05-02 20:08:01 +0000
committerStefan Tauner <stefan.tauner@alumni.tuwien.ac.at>2012-05-02 20:08:01 +0000
commit96c2dfc10f35cca18dc9643dd23c8663d42ed53d (patch)
tree9cd6a4035cfd1b102078d47c0078999a48c02d75
parent3603a28a6d23efea90efb51216a08244e6645bcd (diff)
downloadast2050-flashrom-96c2dfc10f35cca18dc9643dd23c8663d42ed53d.zip
ast2050-flashrom-96c2dfc10f35cca18dc9643dd23c8663d42ed53d.tar.gz
spi25.c: Refactor spi_write_status_register helpers
In r1115 "Write protection handling for Atmel AT25*" the old spi_write_status_register function was duplicated to send WREN and EWSR commands respectively controlled by a new common wrapper function spi_write_status_register without a reason. Both functions' resulting code is equal apart from the opcode used. The code itself does also differ in the macros used, but their value (apart from the opcode) is equal. This patch adds a new parameter for the opcode to the helper function which allows removal of the other one. This relies on the fact that EWSR and WREN have the same INSIZE and OUTSIZE though. If that is really seen as an issue, the sizes could be made parameters too. This patch also changes the wrapper so that it no longer sets the feature bits of the struct flash(ctx) argument. This may result in changed output, because it no longer implicitly disables the debug message in following executions. Since almost all chips had their feature bits fixed in the previous commit, this is a minor problem. Also, spi_write_status_enable has been dead code since r658 or so. Remove it. Corresponding to flashrom svn r1528. Signed-off-by: Stefan Tauner <stefan.tauner@alumni.tuwien.ac.at> Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
-rw-r--r--spi25.c72
1 files changed, 14 insertions, 58 deletions
diff --git a/spi25.c b/spi25.c
index b7e8189..083d85f 100644
--- a/spi25.c
+++ b/spi25.c
@@ -764,63 +764,19 @@ int spi_write_status_enable(struct flashctx *flash)
* This is according the SST25VF016 datasheet, who knows it is more
* generic that this...
*/
-static int spi_write_status_register_ewsr(struct flashctx *flash, int status)
+static int spi_write_status_register_flag(struct flashctx *flash, int status, const unsigned char enable_opcode)
{
int result;
int i = 0;
- struct spi_command cmds[] = {
- {
- /* WRSR requires either EWSR or WREN depending on chip type. */
- .writecnt = JEDEC_EWSR_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_EWSR },
- .readcnt = 0,
- .readarr = NULL,
- }, {
- .writecnt = JEDEC_WRSR_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_WRSR, (unsigned char) status },
- .readcnt = 0,
- .readarr = NULL,
- }, {
- .writecnt = 0,
- .writearr = NULL,
- .readcnt = 0,
- .readarr = NULL,
- }};
-
- result = spi_send_multicommand(flash, cmds);
- if (result) {
- msg_cerr("%s failed during command execution\n",
- __func__);
- /* No point in waiting for the command to complete if execution
- * failed.
- */
- return result;
- }
- /* WRSR performs a self-timed erase before the changes take effect.
- * This may take 50-85 ms in most cases, and some chips apparently
- * allow running RDSR only once. Therefore pick an initial delay of
- * 100 ms, then wait in 10 ms steps until a total of 5 s have elapsed.
+ /*
+ * WRSR requires either EWSR or WREN depending on chip type.
+ * The code below relies on the fact hat EWSR and WREN have the same
+ * INSIZE and OUTSIZE.
*/
- programmer_delay(100 * 1000);
- while (spi_read_status_register(flash) & JEDEC_RDSR_BIT_WIP) {
- if (++i > 490) {
- msg_cerr("Error: WIP bit after WRSR never cleared\n");
- return TIMEOUT_ERROR;
- }
- programmer_delay(10 * 1000);
- }
- return 0;
-}
-
-static int spi_write_status_register_wren(struct flashctx *flash, int status)
-{
- int result;
- int i = 0;
struct spi_command cmds[] = {
{
- /* WRSR requires either EWSR or WREN depending on chip type. */
.writecnt = JEDEC_WREN_OUTSIZE,
- .writearr = (const unsigned char[]){ JEDEC_WREN },
+ .writearr = (const unsigned char[]){ enable_opcode },
.readcnt = 0,
.readarr = NULL,
}, {
@@ -837,8 +793,7 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status)
result = spi_send_multicommand(flash, cmds);
if (result) {
- msg_cerr("%s failed during command execution\n",
- __func__);
+ msg_cerr("%s failed during command execution\n", __func__);
/* No point in waiting for the command to complete if execution
* failed.
*/
@@ -862,17 +817,18 @@ static int spi_write_status_register_wren(struct flashctx *flash, int status)
int spi_write_status_register(struct flashctx *flash, int status)
{
+ int feature_bits = flash->feature_bits;
int ret = 1;
- if (!(flash->feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) {
+ if (!(feature_bits & (FEATURE_WRSR_WREN | FEATURE_WRSR_EWSR))) {
msg_cdbg("Missing status register write definition, assuming "
"EWSR is needed\n");
- flash->feature_bits |= FEATURE_WRSR_EWSR;
+ feature_bits |= FEATURE_WRSR_EWSR;
}
- if (flash->feature_bits & FEATURE_WRSR_WREN)
- ret = spi_write_status_register_wren(flash, status);
- if (ret && (flash->feature_bits & FEATURE_WRSR_EWSR))
- ret = spi_write_status_register_ewsr(flash, status);
+ if (feature_bits & FEATURE_WRSR_WREN)
+ ret = spi_write_status_register_flag(flash, status, JEDEC_WREN);
+ if (ret && (feature_bits & FEATURE_WRSR_EWSR))
+ ret = spi_write_status_register_flag(flash, status, JEDEC_EWSR);
return ret;
}
OpenPOWER on IntegriCloud