diff options
Diffstat (limited to 'include/linux/ihex.h')
-rw-r--r-- | include/linux/ihex.h | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/include/linux/ihex.h b/include/linux/ihex.h index 75c194391869..98cb5ce0b0a0 100644 --- a/include/linux/ihex.h +++ b/include/linux/ihex.h @@ -21,12 +21,24 @@ struct ihex_binrec { uint8_t data[0]; } __attribute__((packed)); +static inline uint16_t ihex_binrec_size(const struct ihex_binrec *p) +{ + return be16_to_cpu(p->len) + sizeof(*p); +} + /* Find the next record, taking into account the 4-byte alignment */ static inline const struct ihex_binrec * +__ihex_next_binrec(const struct ihex_binrec *rec) +{ + const void *p = rec; + + return p + ALIGN(ihex_binrec_size(rec), 4); +} + +static inline const struct ihex_binrec * ihex_next_binrec(const struct ihex_binrec *rec) { - int next = ((be16_to_cpu(rec->len) + 5) & ~3) - 2; - rec = (void *)&rec->data[next]; + rec = __ihex_next_binrec(rec); return be16_to_cpu(rec->len) ? rec : NULL; } @@ -34,18 +46,15 @@ ihex_next_binrec(const struct ihex_binrec *rec) /* Check that ihex_next_binrec() won't take us off the end of the image... */ static inline int ihex_validate_fw(const struct firmware *fw) { - const struct ihex_binrec *rec; - size_t ofs = 0; + const struct ihex_binrec *end, *rec; - while (ofs <= fw->size - sizeof(*rec)) { - rec = (void *)&fw->data[ofs]; + rec = (const void *)fw->data; + end = (const void *)&fw->data[fw->size - sizeof(*end)]; + for (; rec <= end; rec = __ihex_next_binrec(rec)) { /* Zero length marks end of records */ - if (!be16_to_cpu(rec->len)) + if (rec == end && !be16_to_cpu(rec->len)) return 0; - - /* Point to next record... */ - ofs += (sizeof(*rec) + be16_to_cpu(rec->len) + 3) & ~3; } return -EINVAL; } |