diff options
Diffstat (limited to 'libflash/blocklevel.c')
-rw-r--r-- | libflash/blocklevel.c | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/libflash/blocklevel.c b/libflash/blocklevel.c index 9802ad0..d2b7eaa 100644 --- a/libflash/blocklevel.c +++ b/libflash/blocklevel.c @@ -82,6 +82,7 @@ int blocklevel_raw_read(struct blocklevel_device *bl, uint64_t pos, void *buf, u { int rc; + FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len); if (!bl || !bl->read || !buf) { errno = EINVAL; return FLASH_ERR_PARM_ERROR; @@ -104,6 +105,7 @@ int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint6 struct ecc64 *buffer; uint64_t ecc_len = ecc_buffer_size(len); + FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len); if (!bl || !buf) { errno = EINVAL; return FLASH_ERR_PARM_ERROR; @@ -112,6 +114,7 @@ int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint6 if (!ecc_protected(bl, pos, len)) return blocklevel_raw_read(bl, pos, buf, len); + FL_DBG("%s: region has ECC\n", __func__); buffer = malloc(ecc_len); if (!buffer) { errno = ENOMEM; @@ -138,6 +141,7 @@ int blocklevel_raw_write(struct blocklevel_device *bl, uint64_t pos, { int rc; + FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len); if (!bl || !bl->write || !buf) { errno = EINVAL; return FLASH_ERR_PARM_ERROR; @@ -161,6 +165,7 @@ int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf struct ecc64 *buffer; uint64_t ecc_len = ecc_buffer_size(len); + FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len); if (!bl || !buf) { errno = EINVAL; return FLASH_ERR_PARM_ERROR; @@ -169,6 +174,7 @@ int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf if (!ecc_protected(bl, pos, len)) return blocklevel_raw_write(bl, pos, buf, len); + FL_DBG("%s: region has ECC\n", __func__); buffer = malloc(ecc_len); if (!buffer) { errno = ENOMEM; @@ -197,14 +203,17 @@ int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len) return FLASH_ERR_PARM_ERROR; } + FL_DBG("%s: 0x%" PRIx64 "\t0x%" PRIx64 "\n", __func__, pos, len); + /* Programmer may be making a horrible mistake without knowing it */ if (pos & bl->erase_mask) { - fprintf(stderr, "blocklevel_erase: pos (0x%"PRIx64") is not erase block (0x%08x) aligned\n", + FL_ERR("blocklevel_erase: pos (0x%"PRIx64") is not erase block (0x%08x) aligned\n", pos, bl->erase_mask + 1); + return FLASH_ERR_ERASE_BOUNDARY; } if (len & bl->erase_mask) { - fprintf(stderr, "blocklevel_erase: len (0x%"PRIx64") is not erase block (0x%08x) aligned\n", + FL_ERR("blocklevel_erase: len (0x%"PRIx64") is not erase block (0x%08x) aligned\n", len, bl->erase_mask + 1); return FLASH_ERR_ERASE_BOUNDARY; } @@ -238,7 +247,7 @@ int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_ /* Check the validity of what we are being told */ if (erase_granule && *erase_granule != bl->erase_mask + 1) - fprintf(stderr, "blocklevel_get_info: WARNING: erase_granule (0x%08x) and erase_mask" + FL_ERR("blocklevel_get_info: WARNING: erase_granule (0x%08x) and erase_mask" " (0x%08x) don't match\n", *erase_granule, bl->erase_mask + 1); release(bl); @@ -286,10 +295,14 @@ int blocklevel_smart_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t return FLASH_ERR_PARM_ERROR; } + FL_DBG("%s: 0x%" PRIx64 "\t0x%" PRIx64 "\n", __func__, pos, len); + /* Nothing smart needs to be done, pos and len are aligned */ - if ((pos & bl->erase_mask) == 0 && (len & bl->erase_mask) == 0) + if ((pos & bl->erase_mask) == 0 && (len & bl->erase_mask) == 0) { + FL_DBG("%s: Skipping smarts everything is aligned 0x%" PRIx64 " 0x%" PRIx64 + "to 0x%08x\n", __func__, pos, len, bl->erase_mask); return blocklevel_erase(bl, pos, len); - + } block_size = bl->erase_mask + 1; erase_buf = malloc(block_size); if (!erase_buf) { @@ -311,6 +324,9 @@ int blocklevel_smart_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t uint64_t base_pos = pos & ~(bl->erase_mask); uint64_t base_len = pos - base_pos; + FL_DBG("%s: preserving 0x%" PRIx64 "..0x%" PRIx64 "\n", + __func__, base_pos, base_pos + base_len); + /* * Read the entire block in case this is the ONLY block we're * modifying, we may need the end chunk of it later @@ -334,6 +350,8 @@ int blocklevel_smart_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t if (base_pos + base_len + len < base_pos + block_size) { rc = bl->write(bl, pos + len, erase_buf + pos + len, block_size - base_len - len); + FL_DBG("%s: Early exit, everything was in one erase block\n", + __func__); goto out; } @@ -343,6 +361,8 @@ int blocklevel_smart_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t /* Now we should be aligned, best to double check */ if (pos & bl->erase_mask) { + FL_DBG("%s:pos 0x%" PRIx64 " isn't erase_mask 0x%08x aligned\n", + __func__, pos, bl->erase_mask); rc = FLASH_ERR_PARM_ERROR; goto out; } @@ -358,6 +378,8 @@ int blocklevel_smart_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t /* Length should be less than a block now */ if (len > block_size) { + FL_DBG("%s: len 0x%" PRIx64 " is still exceeds block_size 0x%" PRIx64 "\n", + __func__, len, block_size); rc = FLASH_ERR_PARM_ERROR; goto out; } @@ -371,6 +393,9 @@ int blocklevel_smart_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t uint64_t top_pos = pos + len; uint64_t top_len = block_size - len; + FL_DBG("%s: preserving 0x%" PRIx64 "..0x%" PRIx64 "\n", + __func__, top_pos, top_pos + top_len); + rc = bl->read(bl, top_pos, erase_buf, top_len); if (rc) goto out; @@ -403,14 +428,20 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi return FLASH_ERR_PARM_ERROR; } - if (!(bl->flags & WRITE_NEED_ERASE)) + FL_DBG("%s: 0x%" PRIx64 "\t0x%" PRIx64 "\n", __func__, pos, len); + + if (!(bl->flags & WRITE_NEED_ERASE)) { + FL_DBG("%s: backend doesn't need erase\n", __func__); return blocklevel_write(bl, pos, buf, len); + } rc = blocklevel_get_info(bl, NULL, NULL, &erase_size); if (rc) return rc; if (ecc_protected(bl, pos, len)) { + FL_DBG("%s: region has ECC\n", __func__); + len = ecc_buffer_size(len); write_buf_start = malloc(len); @@ -454,9 +485,15 @@ int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const voi goto out; cmp = blocklevel_flashcmp(erase_buf + block_offset, write_buf, size); + FL_DBG("%s: region 0x%08x..0x%08x ", __func__, + erase_block, erase_size); if (cmp != 0) { - if (cmp == -1) + FL_DBG("needs "); + if (cmp == -1) { + FL_DBG("erase and "); bl->erase(bl, erase_block, erase_size); + } + FL_DBG("write\n"); memcpy(erase_buf + block_offset, write_buf, size); rc = bl->write(bl, erase_block, erase_buf, erase_size); if (rc) @@ -494,11 +531,13 @@ static bool insert_bl_prot_range(struct blocklevel_range *ranges, struct bl_prot for (i = 0; i < ranges->n_prot && len > 0; i++) { if (prot[i].start <= pos && prot[i].start + prot[i].len >= pos + len) { len = 0; + FL_DBG("%s: breaking early\n", __func__); break; /* Might as well, the next two conditions can't be true */ } /* Can easily extend this down just by adjusting start */ if (pos <= prot[i].start && pos + len >= prot[i].start) { + FL_DBG("%s: extending start down\n", __func__); prot[i].len += prot[i].start - pos; prot[i].start = pos; pos += prot[i].len; @@ -513,10 +552,13 @@ static bool insert_bl_prot_range(struct blocklevel_range *ranges, struct bl_prot * theres a chunk after */ if (pos >= prot[i].start && pos < prot[i].start + prot[i].len) { + FL_DBG("%s: fits within current range ", __func__); if (prot[i].start + prot[i].len - pos > len) { + FL_DBG("but there is some extra at the end\n"); len -= prot[i].start + prot[i].len - pos; pos = prot[i].start + prot[i].len; } else { + FL_DBG("\n"); len = 0; } } @@ -531,6 +573,9 @@ static bool insert_bl_prot_range(struct blocklevel_range *ranges, struct bl_prot if (len) { int insert_pos = i; struct bl_prot_range *new_ranges = ranges->prot; + + FL_DBG("%s: adding 0x%08x..0x%08x\n", __func__, pos, pos + len); + if (ranges->n_prot == ranges->total_prot) { new_ranges = realloc(ranges->prot, sizeof(range) * ((ranges->n_prot) + PROT_REALLOC_NUM)); @@ -550,10 +595,15 @@ static bool insert_bl_prot_range(struct blocklevel_range *ranges, struct bl_prot /* Probably only worth mergeing when we're low on space */ if (ranges->n_prot + 1 == ranges->total_prot) { + FL_DBG("%s: merging ranges\n", __func__); /* Check to see if we can merge ranges */ for (i = 0; i < ranges->n_prot - 1; i++) { if (prot[i].start + prot[i].len == prot[i + 1].start) { int j; + FL_DBG("%s: merging 0x%" PRIx64 "..0x%" PRIx64 " with " + "0x%" PRIx64 "..0x%" PRIx64 "\n", + __func__, prot[i].start, prot[i].start + prot[i].len, + prot[i + 1].start, prot[i + 1].start + prot[i + 1].len); prot[i].len += prot[i + 1].len; for (j = i + 1; j < ranges->n_prot - 1; j++) memcpy(&prot[j] , &prot[j + 1], sizeof(range)); |