[OpenWrt-Devel] [PATCH 4/8] [ar7] detect AC49x flash partitions
Signed-off-by: Daniel Golle dgo...@allnet.de create mode 100644 target/linux/ar7/files/drivers/mtd/ac49xpart.c create mode 100644 target/linux/ar7/patches-3.3/320-ac49x-mtd-partitions.patch diff --git a/target/linux/ar7/files/drivers/mtd/ac49xpart.c b/target/linux/ar7/files/drivers/mtd/ac49xpart.c new file mode 100644 index 000..1f937f0 --- /dev/null +++ b/target/linux/ar7/files/drivers/mtd/ac49xpart.c @@ -0,0 +1,220 @@ +/* + * AudioCodes AC49x PSPBoot-based flash partition table + * Copyright 2012 Daniel Golle daniel.go...@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include linux/kernel.h +#include linux/slab.h + +#include linux/mtd/mtd.h +#include linux/mtd/partitions.h +#include linux/bootmem.h +#include linux/magic.h +#include linux/module.h + +#include asm/mach-ar7/prom.h + +#define AC49X_MAXENVPARTS 8 + +#define AC49X_PARTTYPE_LOADER 0 +#define AC49X_PARTTYPE_BOOTENV 1 +#define AC49X_PARTTYPE_LINUX 2 +#define AC49X_PARTTYPE_ROOTFS 3 +#define AC49X_PARTTYPE_UNKNOWN 4 +#define AC49X_NUM_PARTTYPES5 + +#define AC49X_FLASH_ADDRMASK 0x00FF + +#define AC49X_LOADER_MAGIC 0x40809000 +#define AC49X_LINUX_MAGIC 0x464c457f /* ELF */ +#define AC49X_BOOTENV_MAGIC0x4578614d /* MaxE */ + +#define ROOTFS_MIN_OFFSET 0xC + +int parse_partvar(const unsigned char *partvar, struct mtd_partition *part) +{ + unsigned int partstart, partend; + unsigned int pnum; + + pnum = sscanf(partvar, 0x%x,0x%x, partstart, partend); + if (pnum != 2) + return 1; + + part-offset = partstart AC49X_FLASH_ADDRMASK; + part-size = partend - partstart; + + return 0; +} + +int detect_parttype(struct mtd_info *master, struct mtd_partition part) +{ + unsigned int magic; + size_t len; + + if (part.size 4) + return -1; + + mtd_read(master, part.offset, sizeof(magic), len, +(uint8_t *)magic); + + if (len != sizeof(magic)) + return -1; + + switch (magic) { + case AC49X_LOADER_MAGIC: + return AC49X_PARTTYPE_LOADER; + case AC49X_LINUX_MAGIC: + return AC49X_PARTTYPE_LINUX; + case SQUASHFS_MAGIC: + case CRAMFS_MAGIC: + case CRAMFS_MAGIC_WEND: + return AC49X_PARTTYPE_ROOTFS; + case AC49X_BOOTENV_MAGIC: + return AC49X_PARTTYPE_BOOTENV; + default: + switch (magic 0xFF) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } + switch (magic 8) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } + return AC49X_PARTTYPE_UNKNOWN; + } +} + +const char *partnames[] = { + loader, + config, + linux, + rootfs, + data +}; + +void gen_partname(unsigned int type, + unsigned int *typenumeration, + struct mtd_partition *part) +{ + char *s = kzalloc(sizeof(char) * 8, GFP_KERNEL); + + (typenumeration[type])++; + if (typenumeration[type] == 1) + sprintf(s, %s, partnames[type]); + else + sprintf(s, %s%d, partnames[type], typenumeration[type]); + + part-name = s; +} + +static int create_mtd_partitions(struct mtd_info *master, +struct mtd_partition **pparts, +struct mtd_part_parser_data *data) +{ + unsigned int envpartnum = 0, linuxpartnum = 0; + unsigned int typenumeration[5] = { 0, 0, 0, 0, 0 }; + unsigned char evn[5]; + const unsigned char *partvar = NULL; + + struct mtd_partition *ac49x_parts; + + ac49x_parts = kzalloc(sizeof(*ac49x_parts) * AC49X_MAXENVPARTS, + GFP_KERNEL); + + if (!ac49x_parts) + return -ENOMEM; + + linuxpartnum = 0; + for (envpartnum = 0; envpartnum AC49X_MAXENVPARTS; envpartnum++) { + struct mtd_partition parsepart; + unsigned int offset, size, type; + int err; + sprintf(evn, mtd%d, envpartnum); + partvar = prom_getenv(evn); + if (!partvar) +
[OpenWrt-Devel] [PATCH 4/8] [ar7] detect AC49x flash partitions
Signed-off-by: Daniel Golle dgo...@allnet.de --- target/linux/ar7/files/drivers/mtd/ac49xpart.c | 199 + .../ar7/patches-3.3/320-ac49x-mtd-partitions.patch | 41 + 2 files changed, 240 insertions(+) create mode 100644 target/linux/ar7/files/drivers/mtd/ac49xpart.c create mode 100644 target/linux/ar7/patches-3.3/320-ac49x-mtd-partitions.patch diff --git a/target/linux/ar7/files/drivers/mtd/ac49xpart.c b/target/linux/ar7/files/drivers/mtd/ac49xpart.c new file mode 100644 index 000..1eb19b5 --- /dev/null +++ b/target/linux/ar7/files/drivers/mtd/ac49xpart.c @@ -0,0 +1,199 @@ +/* + * AudioCodes AC49x PSPBoot-based flash partition table + * Copyright 2012 Daniel Golle daniel.go...@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include linux/kernel.h +#include linux/slab.h + +#include linux/mtd/mtd.h +#include linux/mtd/partitions.h +#include linux/bootmem.h +#include linux/magic.h +#include linux/module.h + +#include asm/mach-ar7/prom.h + +#define AC49X_MAXENVPARTS 8 + +#define AC49X_PARTTYPE_LOADER 0 +#define AC49X_PARTTYPE_BOOTENV 1 +#define AC49X_PARTTYPE_LINUX 2 +#define AC49X_PARTTYPE_ROOTFS 3 +#define AC49X_PARTTYPE_UNKNOWN 4 +#define AC49X_NUM_PARTTYPES5 + +#define AC49X_FLASH_ADDRMASK 0x00FF + +#define AC49X_LOADER_MAGIC 0x40809000 +#define AC49X_LINUX_MAGIC 0x464c457f // ELF +#define AC49X_BOOTENV_MAGIC0x4578614d // MaxE + +#define ROOTFS_MIN_OFFSET 0xC + +int parse_partvar(const unsigned char *partvar, struct mtd_partition *part) +{ + unsigned int partstart, partend; + unsigned int pnum; + pnum = sscanf(partvar, 0x%x,0x%x, partstart, partend); + if (pnum != 2) return 1; + part-offset = partstart AC49X_FLASH_ADDRMASK; + part-size = partend - partstart; + return 0; +} + +int detect_parttype(struct mtd_info *master, struct mtd_partition part) +{ + unsigned int magic; + size_t len; + + if (part.size 4) return -1; + + mtd_read(master, part.offset, sizeof(magic), len, +(uint8_t *)magic); + + if (len != sizeof(magic)) return -1; + + switch (magic) { + case AC49X_LOADER_MAGIC: + return AC49X_PARTTYPE_LOADER; + case AC49X_LINUX_MAGIC: + return AC49X_PARTTYPE_LINUX; + case SQUASHFS_MAGIC: + case CRAMFS_MAGIC: + case CRAMFS_MAGIC_WEND: + return AC49X_PARTTYPE_ROOTFS; + case AC49X_BOOTENV_MAGIC: + return AC49X_PARTTYPE_BOOTENV; + default: + switch (magic 0xFF) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } + switch (magic 8) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } + return AC49X_PARTTYPE_UNKNOWN; + } +} + +const char *partnames[] = { + loader, + config, + linux, + rootfs, + data + }; + +void gen_partname(unsigned int type, unsigned int *typenumeration, struct mtd_partition *part) +{ + char *s = kzalloc(sizeof(char) * 8, GFP_KERNEL); + + (typenumeration[type])++; + if ( typenumeration[type] == 1 ) + sprintf(s, %s, partnames[type]); + else + sprintf(s, %s%d, partnames[type], typenumeration[type]); + + part-name = s; +} + +static int create_mtd_partitions(struct mtd_info *master, +struct mtd_partition **pparts, +struct mtd_part_parser_data *data) +{ + unsigned int envpartnum = 0, linuxpartnum = 0; + unsigned int typenumeration[5] = { 0,0,0,0,0 }; + unsigned char evn[5]; + const unsigned char *partvar = NULL; + + struct mtd_partition *ac49x_parts; + + ac49x_parts = kzalloc(sizeof(*ac49x_parts) * AC49X_MAXENVPARTS, GFP_KERNEL); + if (!ac49x_parts) + return -ENOMEM; + + linuxpartnum=0; + for (envpartnum = 0;
Re: [OpenWrt-Devel] [PATCH 4/8] [ar7] detect AC49x flash partitions
On 15 October 2012 11:43, Daniel Golle dgo...@allnet.de wrote: Signed-off-by: Daniel Golle dgo...@allnet.de --- target/linux/ar7/files/drivers/mtd/ac49xpart.c | 199 + .../ar7/patches-3.3/320-ac49x-mtd-partitions.patch | 41 + 2 files changed, 240 insertions(+) create mode 100644 target/linux/ar7/files/drivers/mtd/ac49xpart.c create mode 100644 target/linux/ar7/patches-3.3/320-ac49x-mtd-partitions.patch diff --git a/target/linux/ar7/files/drivers/mtd/ac49xpart.c b/target/linux/ar7/files/drivers/mtd/ac49xpart.c new file mode 100644 index 000..1eb19b5 --- /dev/null +++ b/target/linux/ar7/files/drivers/mtd/ac49xpart.c @@ -0,0 +1,199 @@ +/* + * AudioCodes AC49x PSPBoot-based flash partition table + * Copyright 2012 Daniel Golle daniel.go...@gmail.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#include linux/kernel.h +#include linux/slab.h + +#include linux/mtd/mtd.h +#include linux/mtd/partitions.h +#include linux/bootmem.h +#include linux/magic.h +#include linux/module.h + +#include asm/mach-ar7/prom.h + +#define AC49X_MAXENVPARTS 8 + +#define AC49X_PARTTYPE_LOADER 0 +#define AC49X_PARTTYPE_BOOTENV 1 +#define AC49X_PARTTYPE_LINUX 2 +#define AC49X_PARTTYPE_ROOTFS 3 +#define AC49X_PARTTYPE_UNKNOWN 4 +#define AC49X_NUM_PARTTYPES5 + +#define AC49X_FLASH_ADDRMASK 0x00FF + +#define AC49X_LOADER_MAGIC 0x40809000 +#define AC49X_LINUX_MAGIC 0x464c457f // ELF +#define AC49X_BOOTENV_MAGIC0x4578614d // MaxE No C99 comments, please. + +#define ROOTFS_MIN_OFFSET 0xC + +int parse_partvar(const unsigned char *partvar, struct mtd_partition *part) +{ + unsigned int partstart, partend; + unsigned int pnum; You should try to keep this as close to the kernel style as possible to make upstreaming it easier, so empty line here, please. + pnum = sscanf(partvar, 0x%x,0x%x, partstart, partend); + if (pnum != 2) return 1; The return needs to be on a separate line. + part-offset = partstart AC49X_FLASH_ADDRMASK; + part-size = partend - partstart; + return 0; +} + +int detect_parttype(struct mtd_info *master, struct mtd_partition part) +{ + unsigned int magic; + size_t len; + + if (part.size 4) return -1; Same here. + + mtd_read(master, part.offset, sizeof(magic), len, +(uint8_t *)magic); + + if (len != sizeof(magic)) return -1; And here. + + switch (magic) { + case AC49X_LOADER_MAGIC: + return AC49X_PARTTYPE_LOADER; + case AC49X_LINUX_MAGIC: + return AC49X_PARTTYPE_LINUX; + case SQUASHFS_MAGIC: + case CRAMFS_MAGIC: + case CRAMFS_MAGIC_WEND: + return AC49X_PARTTYPE_ROOTFS; + case AC49X_BOOTENV_MAGIC: + return AC49X_PARTTYPE_BOOTENV; + default: + switch (magic 0xFF) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } + switch (magic 8) { + case JFFS2_SUPER_MAGIC: + return AC49X_PARTTYPE_ROOTFS; + } Why these two switch statements with only one condition, why not if ((magic 0xFF) == JFFS2_SUPER_MAGIC || (magic 8) == JFFS2_SUPER_MAGIC) + return AC49X_PARTTYPE_UNKNOWN; + } +} + +const char *partnames[] = { + loader, + config, + linux, + rootfs, + data + }; + +void gen_partname(unsigned int type, unsigned int *typenumeration, struct mtd_partition *part) +{ + char *s = kzalloc(sizeof(char) * 8, GFP_KERNEL); + + (typenumeration[type])++; + if ( typenumeration[type] == 1 ) + sprintf(s, %s, partnames[type]); + else + sprintf(s, %s%d, partnames[type], typenumeration[type]); + + part-name = s; +} + +static int