300-block2mtd_init.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. diff -urN linux-2.6.26.orig/arch/x86/kernel/vmlinux_32.lds.S linux-2.6.26/arch/x86/kernel/vmlinux_32.lds.S
  2. --- linux-2.6.26.orig/arch/x86/kernel/vmlinux_32.lds.S 2008-08-13 03:51:12.000000000 +0200
  3. +++ linux-2.6.26/arch/x86/kernel/vmlinux_32.lds.S 2008-08-13 04:08:18.000000000 +0200
  4. @@ -144,6 +144,12 @@
  5. INITCALLS
  6. __initcall_end = .;
  7. }
  8. + .root_initcall.init : AT(ADDR(.root_initcall.init) - LOAD_OFFSET) {
  9. + __root_initcall_start = .;
  10. + INITCALLS_ROOT
  11. + __root_initcall_end = .;
  12. + }
  13. +
  14. .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET) {
  15. __con_initcall_start = .;
  16. *(.con_initcall.init)
  17. diff -urN linux-2.6.26.orig/drivers/mtd/devices/block2mtd.c linux-2.6.26/drivers/mtd/devices/block2mtd.c
  18. --- linux-2.6.26.orig/drivers/mtd/devices/block2mtd.c 2008-08-13 03:51:05.000000000 +0200
  19. +++ linux-2.6.26/drivers/mtd/devices/block2mtd.c 2008-08-13 04:06:43.000000000 +0200
  20. @@ -20,6 +20,8 @@
  21. #include <linux/buffer_head.h>
  22. #include <linux/mutex.h>
  23. #include <linux/mount.h>
  24. +#include <linux/list.h>
  25. +#include <linux/delay.h>
  26. #define VERSION "$Revision: 1.30 $"
  27. @@ -27,6 +29,12 @@
  28. #define ERROR(fmt, args...) printk(KERN_ERR "block2mtd: " fmt "\n" , ## args)
  29. #define INFO(fmt, args...) printk(KERN_INFO "block2mtd: " fmt "\n" , ## args)
  30. +struct retry {
  31. + struct list_head list;
  32. + const char *val;
  33. +};
  34. +
  35. +static LIST_HEAD(retry_list);
  36. /* Info for the block device */
  37. struct block2mtd_dev {
  38. @@ -38,10 +46,34 @@
  39. char devname[0];
  40. };
  41. +static int block2mtd_setup2(const char *val);
  42. /* Static info about the MTD, used in cleanup_module */
  43. static LIST_HEAD(blkmtd_device_list);
  44. +static int add_retry(const char *val) {
  45. + struct retry *r = kmalloc(sizeof(struct retry), GFP_KERNEL);
  46. +
  47. + INIT_LIST_HEAD(&r->list);
  48. + r->val = val;
  49. + list_add(&r->list, &retry_list);
  50. +
  51. + return 0;
  52. +}
  53. +
  54. +static int __init process_retries(void) {
  55. + struct list_head *p, *tmp;
  56. +
  57. + list_for_each_safe(p, tmp, &retry_list) {
  58. + struct retry *r = list_entry(p, struct retry, list);
  59. + block2mtd_setup2(r->val);
  60. + msleep(100);
  61. + list_del(p);
  62. + kfree(r);
  63. + }
  64. + return 0;
  65. +}
  66. +rootfs_initcall(process_retries);
  67. static struct page *page_read(struct address_space *mapping, int index)
  68. {
  69. @@ -517,7 +549,9 @@
  70. if (token[2] && (strlen(token[2]) + 1 > 80))
  71. parse_err("mtd device name too long");
  72. - add_device(name, erase_size, token[2]);
  73. + if (add_device(name, erase_size, token[2]) == NULL) {
  74. + add_retry(val);
  75. + }
  76. return 0;
  77. }
  78. diff -urN linux-2.6.26.orig/include/asm-generic/vmlinux.lds.h linux-2.6.26/include/asm-generic/vmlinux.lds.h
  79. --- linux-2.6.26.orig/include/asm-generic/vmlinux.lds.h 2008-08-13 03:51:08.000000000 +0200
  80. +++ linux-2.6.26/include/asm-generic/vmlinux.lds.h 2008-08-13 04:09:04.000000000 +0200
  81. @@ -338,12 +338,14 @@
  82. *(.initcall4s.init) \
  83. *(.initcall5.init) \
  84. *(.initcall5s.init) \
  85. - *(.initcallrootfs.init) \
  86. *(.initcall6.init) \
  87. *(.initcall6s.init) \
  88. *(.initcall7.init) \
  89. *(.initcall7s.init)
  90. +#define INITCALLS_ROOT \
  91. + *(.initcallrootfs.init)
  92. +
  93. #define PERCPU(align) \
  94. . = ALIGN(align); \
  95. __per_cpu_start = .; \
  96. diff -urN linux-2.6.26.orig/init/do_mounts.c linux-2.6.26/init/do_mounts.c
  97. --- linux-2.6.26.orig/init/do_mounts.c 2008-08-13 03:51:11.000000000 +0200
  98. +++ linux-2.6.26/init/do_mounts.c 2008-08-13 04:00:22.000000000 +0200
  99. @@ -173,16 +173,8 @@
  100. return 1;
  101. }
  102. -static unsigned int __initdata root_delay;
  103. -static int __init root_delay_setup(char *str)
  104. -{
  105. - root_delay = simple_strtoul(str, NULL, 0);
  106. - return 1;
  107. -}
  108. -
  109. __setup("rootflags=", root_data_setup);
  110. __setup("rootfstype=", fs_names_setup);
  111. -__setup("rootdelay=", root_delay_setup);
  112. static void __init get_fs_names(char *page)
  113. {
  114. @@ -358,18 +350,6 @@
  115. {
  116. int is_floppy;
  117. - if (root_delay) {
  118. - printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
  119. - root_delay);
  120. - ssleep(root_delay);
  121. - }
  122. -
  123. - /* wait for the known devices to complete their probing */
  124. - while (driver_probe_done() != 0)
  125. - msleep(100);
  126. -
  127. - md_run_setup();
  128. -
  129. if (saved_root_name[0]) {
  130. root_device_name = saved_root_name;
  131. if (!strncmp(root_device_name, "mtd", 3)) {
  132. diff -urN linux-2.6.26.orig/init/main.c linux-2.6.26/init/main.c
  133. --- linux-2.6.26.orig/init/main.c 2008-08-13 03:51:11.000000000 +0200
  134. +++ linux-2.6.26/init/main.c 2008-08-13 04:06:01.000000000 +0200
  135. @@ -70,6 +70,7 @@
  136. #ifdef CONFIG_X86_LOCAL_APIC
  137. #include <asm/smp.h>
  138. #endif
  139. +#include "do_mounts.h"
  140. /*
  141. * This is one of the first .c files built. Error out early if we have compiler
  142. @@ -737,12 +738,13 @@
  143. extern initcall_t __initcall_start[], __initcall_end[];
  144. +extern initcall_t __root_initcall_start[], __root_initcall_end[];
  145. -static void __init do_initcalls(void)
  146. +static void __init do_initcalls(initcall_t *start, initcall_t *end)
  147. {
  148. initcall_t *call;
  149. - for (call = __initcall_start; call < __initcall_end; call++)
  150. + for (call = start; call < end; call++)
  151. do_one_initcall(*call);
  152. /* Make sure there is no pending stuff from the initcall sequence */
  153. @@ -763,7 +765,7 @@
  154. usermodehelper_init();
  155. driver_init();
  156. init_irq_proc();
  157. - do_initcalls();
  158. + do_initcalls(__initcall_start, __initcall_end);
  159. }
  160. static int __initdata nosoftlockup;
  161. @@ -835,6 +837,13 @@
  162. panic("No init found. Try passing init= option to kernel.");
  163. }
  164. +static unsigned int __initdata root_delay;
  165. +static int __init root_delay_setup(char *str)
  166. +{
  167. + root_delay = simple_strtoul(str, NULL, 0);
  168. + return 1;
  169. +}
  170. +__setup("rootdelay=", root_delay_setup);
  171. static int __init kernel_init(void * unused)
  172. {
  173. lock_kernel();
  174. @@ -875,7 +884,16 @@
  175. if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
  176. ramdisk_execute_command = NULL;
  177. - prepare_namespace();
  178. + if (root_delay) {
  179. + printk(KERN_INFO "Waiting %desc before mounting root device...\n",
  180. + root_delay);
  181. + ssleep(root_delay);
  182. + }
  183. + while (driver_probe_done() != 0)
  184. + msleep(100);
  185. + md_run_setup();
  186. + do_initcalls(__root_initcall_start, __root_initcall_end);
  187. + prepare_namespace();
  188. }
  189. /*