4 * Maintainers: http://www.nslu2-linux.org/
5 * Initial port: Mark Rakes <mrakes AT mac.com>
7 * "Parse" the fixed partition table of the Linksys NSLU2 and
8 * produce a Linux partition array to match.
11 #include <linux/kernel.h>
12 #include <linux/slab.h>
13 #include <linux/init.h>
14 #include <linux/vmalloc.h>
15 #include <linux/mtd/mtd.h>
16 #include <linux/mtd/partitions.h>
18 /* info we know about the NSLU2's flash setup:
20 * Num Partition offset size
21 * --- --------- ---------- -----------
22 * 0 RedBoot 0x00000000 0x00040000
23 * 1 System Configuration 0x00040000 0x00020000
24 * 2 Kernel 0x00060000 0x00100000
25 * 3 Ramdisk 0x00160000 0x006a0000
27 #define NSLU2_NUM_FLASH_PARTITIONS 4
28 #define NSLU2_FLASH_PART0_NAME "RedBoot"
29 #define NSLU2_FLASH_PART0_OFFSET 0x00000000
30 #define NSLU2_FLASH_PART0_SIZE 0x00040000
31 #define NSLU2_FLASH_PART1_NAME "System Configuration"
32 #define NSLU2_FLASH_PART1_OFFSET (NSLU2_FLASH_PART0_OFFSET + NSLU2_FLASH_PART0_SIZE)
33 #define NSLU2_FLASH_PART1_SIZE 0x00020000
34 #define NSLU2_FLASH_PART2_NAME "Kernel"
35 #define NSLU2_FLASH_PART2_OFFSET (NSLU2_FLASH_PART1_OFFSET + NSLU2_FLASH_PART1_SIZE)
36 #define NSLU2_FLASH_PART2_SIZE 0x00100000
37 #define NSLU2_FLASH_PART3_NAME "Ramdisk"
38 #define NSLU2_FLASH_PART3_OFFSET (NSLU2_FLASH_PART2_OFFSET + NSLU2_FLASH_PART2_SIZE)
39 #define NSLU2_FLASH_PART3_SIZE 0x006a0000
41 static int parse_nslu2_partitions(struct mtd_info *master,
42 struct mtd_partition **pparts,
43 unsigned long flash_start)
45 struct mtd_partition *parts;
46 int ret = 0, namelen = 0;
49 namelen = strlen(NSLU2_FLASH_PART0_NAME) +
50 strlen(NSLU2_FLASH_PART1_NAME) +
51 strlen(NSLU2_FLASH_PART2_NAME) +
52 strlen(NSLU2_FLASH_PART3_NAME) +
53 NSLU2_NUM_FLASH_PARTITIONS; /*4 strings + each terminator */
55 parts = kmalloc(sizeof(*parts)*NSLU2_NUM_FLASH_PARTITIONS + namelen, GFP_KERNEL);
61 memset(parts, 0, sizeof(*parts)*NSLU2_NUM_FLASH_PARTITIONS + namelen);
62 names = (char *)&parts[NSLU2_NUM_FLASH_PARTITIONS];
64 /* RedBoot partition */
65 parts[0].size = NSLU2_FLASH_PART0_SIZE;
66 parts[0].offset = NSLU2_FLASH_PART0_OFFSET;
67 parts[0].name = NSLU2_FLASH_PART0_NAME;
68 parts[0].mask_flags = MTD_WRITEABLE; /* readonly */
69 strcpy(names, NSLU2_FLASH_PART0_NAME);
70 names += strlen(names)+1;
71 /* System Configuration */
72 parts[1].size = NSLU2_FLASH_PART1_SIZE;
73 parts[1].offset = NSLU2_FLASH_PART1_OFFSET;
74 parts[1].name = NSLU2_FLASH_PART1_NAME;
75 parts[1].mask_flags = MTD_WRITEABLE; /* readonly */
76 strcpy(names, NSLU2_FLASH_PART1_NAME);
77 names += strlen(names)+1;
79 parts[2].size = NSLU2_FLASH_PART2_SIZE;
80 parts[2].offset = NSLU2_FLASH_PART2_OFFSET;
81 parts[2].name = NSLU2_FLASH_PART2_NAME;
82 parts[2].mask_flags = MTD_WRITEABLE; /* readonly */
83 strcpy(names, NSLU2_FLASH_PART2_NAME);
84 names += strlen(names)+1;
86 parts[3].size = NSLU2_FLASH_PART3_SIZE;
87 parts[3].offset = NSLU2_FLASH_PART3_OFFSET;
88 parts[3].name = NSLU2_FLASH_PART3_NAME;
89 parts[3].mask_flags = MTD_WRITEABLE; /* readonly */
90 strcpy(names, NSLU2_FLASH_PART3_NAME);
91 names += strlen(names)+1;
93 ret = NSLU2_NUM_FLASH_PARTITIONS;
99 static struct mtd_part_parser nslu2_parser = {
100 .owner = THIS_MODULE,
101 .parse_fn = parse_nslu2_partitions,
105 static int __init nslu2_parser_init(void)
107 return register_mtd_parser(&nslu2_parser);
110 static void __exit nslu2_parser_exit(void)
112 deregister_mtd_parser(&nslu2_parser);
115 module_init(nslu2_parser_init);
116 module_exit(nslu2_parser_exit);
118 MODULE_LICENSE("GPL");
119 MODULE_AUTHOR("Mark Rakes");
120 MODULE_DESCRIPTION("Parsing code for NSLU2 flash tables");