X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmtd%2Fredboot.c;h=0212a7df84c4d2f091100590bd87a411804e7a76;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=3e279992f6a90dd8efc9b82857b6c0ad512022e2;hpb=db216c3d5e4c040e557a50f8f5d35d5c415e8c1c;p=linux-2.6.git diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 3e279992f..0212a7df8 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c @@ -1,5 +1,5 @@ /* - * $Id: redboot.c,v 1.11 2003/05/21 10:39:26 dwmw2 Exp $ + * $Id: redboot.c,v 1.15 2004/08/10 07:55:16 dwmw2 Exp $ * * Parse RedBoot-style Flash Image System (FIS) tables and * produce a Linux partition array to match. @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -48,21 +49,24 @@ static int parse_redboot_partitions(struct mtd_info *master, char *names; char *nullname; int namelen = 0; + int nulllen = 0; +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED static char nullstring[] = "unallocated"; +#endif - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + buf = vmalloc(master->erasesize); if (!buf) return -ENOMEM; /* Read the start of the last erase block */ ret = master->read(master, master->size - master->erasesize, - PAGE_SIZE, &retlen, (void *)buf); + master->erasesize, &retlen, (void *)buf); if (ret) goto out; - if (retlen != PAGE_SIZE) { + if (retlen != master->erasesize) { ret = -EIO; goto out; } @@ -80,7 +84,7 @@ static int parse_redboot_partitions(struct mtd_info *master, goto out; } - for (i = 0; i < PAGE_SIZE / sizeof(struct fis_image_desc); i++) { + for (i = 0; i < master->erasesize / sizeof(struct fis_image_desc); i++) { struct fis_list *new_fl, **prev; if (buf[i].name[0] == 0xff) @@ -112,48 +116,69 @@ static int parse_redboot_partitions(struct mtd_info *master, nrparts++; } - if (fl->img->flash_base) +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + if (fl->img->flash_base) { nrparts++; + nulllen = sizeof(nullstring); + } for (tmp_fl = fl; tmp_fl->next; tmp_fl = tmp_fl->next) { - if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize < tmp_fl->next->img->flash_base) + if (tmp_fl->img->flash_base + tmp_fl->img->size + master->erasesize <= tmp_fl->next->img->flash_base) { nrparts++; + nulllen = sizeof(nullstring); + } } - parts = kmalloc(sizeof(*parts)*nrparts + sizeof(nullstring) + namelen, GFP_KERNEL); +#endif + parts = kmalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL); if (!parts) { ret = -ENOMEM; goto out; } - memset(parts, 0, sizeof(*parts)*nrparts + namelen); + memset(parts, 0, sizeof(*parts)*nrparts + nulllen + namelen); - /* FIXME: Include nullname only if it's used */ nullname = (char *)&parts[nrparts]; - sprintf(nullname, nullstring); - names = nullname + sizeof(nullstring); +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + if (nulllen > 0) { + strcpy(nullname, nullstring); + } +#endif + names = nullname + nulllen; i=0; +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED if (fl->img->flash_base) { parts[0].name = nullname; parts[0].size = fl->img->flash_base; parts[0].offset = 0; + i++; } +#endif for ( ; iimg->size; parts[i].offset = fl->img->flash_base; parts[i].name = names; strcpy(names, fl->img->name); +#ifdef CONFIG_MTD_REDBOOT_PARTS_READONLY + if (!memcmp(names, "RedBoot", 8) || + !memcmp(names, "RedBoot config", 15) || + !memcmp(names, "FIS directory", 14)) { + parts[i].mask_flags = MTD_WRITEABLE; + } +#endif names += strlen(names)+1; - if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize < fl->next->img->flash_base) { +#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED + if(fl->next && fl->img->flash_base + fl->img->size + master->erasesize <= fl->next->img->flash_base) { i++; parts[i].offset = parts[i-1].size + parts[i-1].offset; parts[i].size = fl->next->img->flash_base - parts[i].offset; parts[i].name = nullname; } +#endif tmp_fl = fl; fl = fl->next; kfree(tmp_fl); @@ -166,7 +191,7 @@ static int parse_redboot_partitions(struct mtd_info *master, fl = fl->next; kfree(old); } - kfree(buf); + vfree(buf); return ret; }