autoprobing can fail and this error has to be reported up the call stack. Signed-off-by: Øyvind Harboe <oyvind.harboe@zylin.com>tags/v0.5.0-rc1
@@ -197,7 +197,7 @@ struct flash_bank *get_flash_bank_by_name_noprobe(const char *name) | |||
return NULL; | |||
} | |||
struct flash_bank *get_flash_bank_by_name(const char *name) | |||
int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result) | |||
{ | |||
struct flash_bank *bank; | |||
int retval; | |||
@@ -210,11 +210,12 @@ struct flash_bank *get_flash_bank_by_name(const char *name) | |||
if (retval != ERROR_OK) | |||
{ | |||
LOG_ERROR("auto_probe failed %d\n", retval); | |||
return NULL; | |||
return retval; | |||
} | |||
} | |||
return bank; | |||
*bank_result = bank; | |||
return ERROR_OK; | |||
} | |||
int get_flash_bank_by_num(int num, struct flash_bank **bank) | |||
@@ -238,8 +239,9 @@ int get_flash_bank_by_num(int num, struct flash_bank **bank) | |||
return ERROR_OK; | |||
} | |||
/* lookup flash bank by address */ | |||
struct flash_bank *get_flash_bank_by_addr(struct target *target, uint32_t addr) | |||
/* lookup flash bank by address, bank not found is success, but | |||
* result_bank is set to NULL. */ | |||
int get_flash_bank_by_addr(struct target *target, uint32_t addr, bool check, struct flash_bank **result_bank) | |||
{ | |||
struct flash_bank *c; | |||
@@ -252,14 +254,22 @@ struct flash_bank *get_flash_bank_by_addr(struct target *target, uint32_t addr) | |||
if (retval != ERROR_OK) | |||
{ | |||
LOG_ERROR("auto_probe failed %d\n", retval); | |||
return NULL; | |||
return retval; | |||
} | |||
/* check whether address belongs to this flash bank */ | |||
if ((addr >= c->base) && (addr <= c->base + (c->size - 1)) && target == c->target) | |||
return c; | |||
{ | |||
*result_bank = c; | |||
return ERROR_OK; | |||
} | |||
} | |||
LOG_ERROR("No flash at address 0x%08" PRIx32 "\n", addr); | |||
return NULL; | |||
*result_bank = NULL; | |||
if (check) | |||
{ | |||
LOG_ERROR("No flash at address 0x%08" PRIx32 "\n", addr); | |||
return ERROR_FAIL; | |||
} | |||
return ERROR_OK; | |||
} | |||
int default_flash_mem_blank_check(struct flash_bank *bank) | |||
@@ -379,8 +389,9 @@ static int flash_iterate_address_range(struct target *target, | |||
int last = -1; | |||
int i; | |||
if ((c = get_flash_bank_by_addr(target, addr)) == NULL) | |||
return ERROR_FLASH_DST_OUT_OF_BANK; /* no corresponding bank found */ | |||
int retval = get_flash_bank_by_addr(target, addr, true, &c); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if (c->size == 0 || c->num_sectors == 0) | |||
{ | |||
@@ -588,7 +599,11 @@ int flash_write_unlock(struct target *target, struct image *image, | |||
} | |||
/* find the corresponding flash bank */ | |||
if ((c = get_flash_bank_by_addr(target, run_address)) == NULL) | |||
int retval; | |||
retval = get_flash_bank_by_addr(target, run_address, false, &c); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if (c == NULL) | |||
{ | |||
section++; /* and skip it */ | |||
section_offset = 0; | |||
@@ -168,7 +168,7 @@ int default_flash_mem_blank_check(struct flash_bank *bank); | |||
* bank number: when two str9x banks are defined, then 'str9x.1' refers | |||
* to the second. | |||
*/ | |||
struct flash_bank *get_flash_bank_by_name(const char *name); | |||
int get_flash_bank_by_name(const char *name, struct flash_bank **bank_result); | |||
/** | |||
* Returns the flash bank specified by @a name, which matches the | |||
* driver name and a suffix (option) specify the driver-specific | |||
@@ -206,8 +206,9 @@ struct flash_bank *get_flash_bank_by_num_noprobe(int num); | |||
* Returns the flash bank located at a specified address. | |||
* @param target The target, presumed to contain one or more banks. | |||
* @param addr An address that is within the range of the bank. | |||
* @param check return ERROR_OK and result_bank NULL if the bank does not exist | |||
* @returns The struct flash_bank located at @a addr, or NULL. | |||
*/ | |||
struct flash_bank *get_flash_bank_by_addr(struct target *target, uint32_t addr); | |||
int get_flash_bank_by_addr(struct target *target, uint32_t addr, bool check, struct flash_bank **result_bank); | |||
#endif // FLASH_NOR_CORE_H |
@@ -35,7 +35,9 @@ COMMAND_HELPER(flash_command_get_bank, unsigned name_index, | |||
struct flash_bank **bank) | |||
{ | |||
const char *name = CMD_ARGV[name_index]; | |||
*bank = get_flash_bank_by_name(name); | |||
int retval = get_flash_bank_by_name(name, bank); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if (*bank) | |||
return ERROR_OK; | |||
@@ -238,11 +240,9 @@ COMMAND_HANDLER(handle_flash_erase_address_command) | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
p = get_flash_bank_by_addr(target, address); | |||
if (p == NULL) | |||
{ | |||
return ERROR_FAIL; | |||
} | |||
retval = get_flash_bank_by_addr(target, address, true, &p); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
/* We can't know if we did a resume + halt, in which case we no longer know the erased state */ | |||
flash_set_dirty(); | |||
@@ -544,12 +544,9 @@ COMMAND_HANDLER(handle_flash_fill_command) | |||
{ | |||
struct flash_bank *bank; | |||
bank = get_flash_bank_by_addr(target, address); | |||
if (bank == NULL) | |||
{ | |||
retval = ERROR_FAIL; | |||
retval = get_flash_bank_by_addr(target, address, true, &bank ); | |||
if (retval != ERROR_OK) | |||
goto done; | |||
} | |||
cur_size = MIN((count * wordsize - wrote), chunksize); | |||
err = flash_driver_write(bank, chunk, address - bank->base + wrote, cur_size); | |||