Check for a terminating LAR member which tells us that no further LAR member except the bootblock will be found after this member. The LAR member has a normal MAGIC, but all other parts of struct lar_header are 0xff. That way, adding a new member in place of the terminating member will not need an erase cycle.
Signed-off-by: Carl-Daniel Hailfinger c-d.hailfinger.devel.2006@gmx.net
Index: LinuxBIOSv3-larplaceholder/lib/lar.c =================================================================== --- LinuxBIOSv3-larplaceholder/lib/lar.c (Revision 546) +++ LinuxBIOSv3-larplaceholder/lib/lar.c (Arbeitskopie) @@ -58,7 +58,7 @@
int find_file(const struct mem_file *archive, const char *filename, struct mem_file *result) { - char *walk, *fullname; + char *walk, *fullname, *tmp; struct lar_header *header;
printk(BIOS_INFO, "LAR: Attempting to open '%s'.\n", filename); @@ -105,10 +105,24 @@ for (walk = archive->start; (walk < (char *)(archive->start + archive->len - sizeof(struct lar_header))) && (walk >= (char *)archive->start); walk += 16) { - if (strncmp(walk, MAGIC, 8) != 0) + if (strncmp(walk, MAGIC, sizeof(header->magic)) != 0) continue;
header = (struct lar_header *)walk; + /* The loop below deserves an explanation: The final iteration + * of the loop will access the byte after the header. If that + * iteration has been reached, all checked bytes in the header + * were 0xff. This saves one state variable. + */ + for (tmp = walk + sizeof(header->magic); + tmp <= walk + sizeof(*header); tmp++) { + if (*tmp != (char)0xff) + break; + } + if (tmp == walk + sizeof(*header)) { + printk(BIOS_SPEW, "LAR: termination pseudomember reached.\n"); + break; + } fullname = walk + sizeof(struct lar_header);
printk(BIOS_SPEW, "LAR: seen member %s\n", fullname);