[ixp4xx] move the latch-led driver into a separated patch
[openwrt.git] / target / linux / ixp4xx / patches-2.6.23 / 096-kexec_cmdline.patch
1 Index: linux-2.6.23.17/kernel/ksysfs.c
2 ===================================================================
3 --- linux-2.6.23.17.orig/kernel/ksysfs.c
4 +++ linux-2.6.23.17/kernel/ksysfs.c
5 @@ -49,6 +49,165 @@ KERNEL_ATTR_RW(uevent_helper);
6  #endif
7  
8  #ifdef CONFIG_KEXEC
9 +
10 +#include <asm/setup.h>
11 +
12 +extern unsigned long kexec_boot_params;
13 +
14 +char kexec_cmdline[COMMAND_LINE_SIZE] = "";
15 +
16 +static void
17 +replace_cmdline_tag(void)
18 +{
19 +       char *t;
20 +       struct tag *real;
21 +       struct tag *copy;
22 +       struct tag *rend;
23 +       int i;
24 +
25 +/* TODO: check the return params */
26 +       t = kmalloc(KEXEC_BOOT_PARAMS_SIZE + COMMAND_LINE_SIZE, GFP_KERNEL);
27 +       memset((void *)t, 0, KEXEC_BOOT_PARAMS_SIZE + COMMAND_LINE_SIZE);
28 +
29 +/* TODO: validate that the boot params are ATAGS, in fact */
30 +
31 +       copy = (struct tag *)t;
32 +       real = (struct tag *)kexec_boot_params;
33 +       rend = (struct tag *)(kexec_boot_params + KEXEC_BOOT_PARAMS_SIZE);
34 +       while ((real->hdr.size) && (real < rend)) {
35 +               if (real->hdr.tag != ATAG_CMDLINE) {
36 +                       memcpy((void *)copy, (void *)real, real->hdr.size * 4);
37 +                       copy = tag_next(copy);
38 +               }
39 +               real = tag_next(real);
40 +       }
41 +
42 +/* TODO: validate that we have enough space in the buffer */
43 +       
44 +       i = strlen(kexec_cmdline);
45 +       if (i) {
46 +               copy->hdr.tag = ATAG_CMDLINE;
47 +               copy->hdr.size = (sizeof(struct tag_header) + i + 1 + 4) >> 2;
48 +               strcpy(copy->u.cmdline.cmdline, kexec_cmdline);
49 +               copy = tag_next(copy);
50 +       }
51 +
52 +       copy->hdr.tag = ATAG_NONE;            /* Empty tag ends list */
53 +       copy->hdr.size = 0;                   /* zero length */
54 +
55 +/* TODO: validate that the temporary buffer isn't too full */
56 +
57 +       memcpy((void *)kexec_boot_params, (void *)t, KEXEC_BOOT_PARAMS_SIZE);
58 +
59 +       kfree(t);  /* Don't forget to free the big buffer we used */
60 +}
61 +
62 +static ssize_t kexec_cmdline_show(struct kset *kset, char *page)
63 +{
64 +       return sprintf(page, "%s\n", kexec_cmdline);
65 +}
66 +
67 +static ssize_t kexec_cmdline_store(struct kset *kset, const char *page,
68 +                                  size_t count)
69 +{
70 +       if ((count + 1) > COMMAND_LINE_SIZE)
71 +               count = COMMAND_LINE_SIZE;
72 +       memcpy(kexec_cmdline, page, count);
73 +       kexec_cmdline[count] = '\0';
74 +       if (count && (kexec_cmdline[count - 1] == '\n'))
75 +               kexec_cmdline[count - 1] = '\0';
76 +       replace_cmdline_tag();
77 +       return count;
78 +}
79 +KERNEL_ATTR_RW(kexec_cmdline);
80 +
81 +static ssize_t kexec_boot_params_show(struct kset *kset, char *page)
82 +{
83 +       unsigned long *p;
84 +       char buf[PAGE_SIZE];
85 +       int keep_doing;
86 +
87 +       p = (unsigned long *)kexec_boot_params;
88 +
89 +       /* if this doesn't look like atags, just print first few words */
90 +       if (p[1] != ATAG_CORE)
91 +               return sprintf(page, "0x%lx 0x%lx 0x%lx 0x%lx\n",
92 +                              p[0], p[1], p[2], p[3]);
93 +
94 +       /* carefully walk the atag list, and print out the structure */
95 +       keep_doing = 1;
96 +       do {
97 +               switch (p[1]) {
98 +               case ATAG_CORE:
99 +                       /* watch out, core tag is permitted to be empty */
100 +                       if (p[0] == 5)
101 +                               sprintf(buf,
102 +                                       "CORE flg=%ld pgsz=%ld rdev=0x%lx\n",
103 +                                       p[2], p[3], p[4]);
104 +                       else
105 +                               sprintf(buf,"CORE\n");
106 +                       break;
107 +               case ATAG_MEM:
108 +                       sprintf(buf,"MEM  %ldM@0x%lx\n", p[2] / (1024 * 1024),
109 +                               p[3]);
110 +                       break;
111 +               case ATAG_VIDEOTEXT:
112 +                       sprintf(buf,"VIDEOTEXT sz=%ld\n", p[0]);
113 +                       break;
114 +               case ATAG_RAMDISK:
115 +                       sprintf(buf,"RAMDISK prmpt=%ld %ldK@0x%lx\n",
116 +                               p[2], p[3], p[4]);
117 +                       break;
118 +               case ATAG_INITRD2:
119 +                       sprintf(buf,"INITRD2 %ldK@0x%lx\n", p[3] / 1024, p[2]);
120 +                       break;
121 +               case ATAG_SERIAL:
122 +                       sprintf(buf,"SERIAL high=0x%08lx low=0x%08lx\n",
123 +                               p[3], p[2]);
124 +                       break;
125 +               case ATAG_REVISION:
126 +                       sprintf(buf,"REVISION rev=%ld\n", p[2]);
127 +                       break;
128 +               case ATAG_VIDEOLFB:
129 +                       sprintf(buf,"VIDEOLFB sz=%ld\n", p[0]);
130 +                       break;
131 +               case ATAG_CMDLINE:
132 +                       sprintf(buf,"CMD  \"%s\"\n", (char *)&p[2]);
133 +                       break;
134 +               case ATAG_NONE:
135 +                       sprintf(buf,"NONE\n");
136 +                       keep_doing = 0;
137 +                       break;
138 +               default:
139 +                       sprintf(buf,"-unknown- sz=%ld\n", p[0]);
140 +                       break;
141 +               }
142 +
143 +               /* carefully add to page */
144 +               if ((strlen(buf) + strlen(page)) < PAGE_SIZE) {
145 +                       strcat(page, buf);
146 +               } else {
147 +                       keep_doing = 0;
148 +               }
149 +
150 +               /* stop when we encounter a header length of 0 */
151 +               if (p[0] == 0)
152 +                       keep_doing = 0;
153 +
154 +               /* go to the next tag */
155 +               p += p[0];
156 +
157 +               /* stop if we walked off the end of the buffer */
158 +               if (p > (unsigned long *)(kexec_boot_params +
159 +                                         KEXEC_BOOT_PARAMS_SIZE))
160 +                       keep_doing = 0;
161 +
162 +       } while (keep_doing);
163 +
164 +       return (strlen(page));
165 +}
166 +KERNEL_ATTR_RO(kexec_boot_params);
167 +
168  static ssize_t kexec_loaded_show(struct kset *kset, char *page)
169  {
170         return sprintf(page, "%d\n", !!kexec_image);
171 @@ -95,6 +254,8 @@ static struct attribute * kernel_attrs[]
172  #ifdef CONFIG_KEXEC
173         &kexec_loaded_attr.attr,
174         &kexec_crash_loaded_attr.attr,
175 +       &kexec_cmdline_attr.attr,
176 +       &kexec_boot_params_attr.attr,
177  #endif
178         NULL
179  };