Merge tag 'dlm-3.19' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm
[linux-2.6-microblaze.git] / arch / x86 / boot / cmdline.c
1 /* -*- linux-c -*- ------------------------------------------------------- *
2  *
3  *   Copyright (C) 1991, 1992 Linus Torvalds
4  *   Copyright 2007 rPath, Inc. - All Rights Reserved
5  *
6  *   This file is part of the Linux kernel, and is made available under
7  *   the terms of the GNU General Public License version 2.
8  *
9  * ----------------------------------------------------------------------- */
10
11 /*
12  * Simple command-line parser for early boot.
13  */
14
15 #include "boot.h"
16
17 static inline int myisspace(u8 c)
18 {
19         return c <= ' ';        /* Close enough approximation */
20 }
21
22 /*
23  * Find a non-boolean option, that is, "option=argument".  In accordance
24  * with standard Linux practice, if this option is repeated, this returns
25  * the last instance on the command line.
26  *
27  * Returns the length of the argument (regardless of if it was
28  * truncated to fit in the buffer), or -1 on not found.
29  */
30 int __cmdline_find_option(unsigned long cmdline_ptr, const char *option, char *buffer, int bufsize)
31 {
32         addr_t cptr;
33         char c;
34         int len = -1;
35         const char *opptr = NULL;
36         char *bufptr = buffer;
37         enum {
38                 st_wordstart,   /* Start of word/after whitespace */
39                 st_wordcmp,     /* Comparing this word */
40                 st_wordskip,    /* Miscompare, skip */
41                 st_bufcpy       /* Copying this to buffer */
42         } state = st_wordstart;
43
44         if (!cmdline_ptr)
45                 return -1;      /* No command line */
46
47         cptr = cmdline_ptr & 0xf;
48         set_fs(cmdline_ptr >> 4);
49
50         while (cptr < 0x10000 && (c = rdfs8(cptr++))) {
51                 switch (state) {
52                 case st_wordstart:
53                         if (myisspace(c))
54                                 break;
55
56                         /* else */
57                         state = st_wordcmp;
58                         opptr = option;
59                         /* fall through */
60
61                 case st_wordcmp:
62                         if (c == '=' && !*opptr) {
63                                 len = 0;
64                                 bufptr = buffer;
65                                 state = st_bufcpy;
66                         } else if (myisspace(c)) {
67                                 state = st_wordstart;
68                         } else if (c != *opptr++) {
69                                 state = st_wordskip;
70                         }
71                         break;
72
73                 case st_wordskip:
74                         if (myisspace(c))
75                                 state = st_wordstart;
76                         break;
77
78                 case st_bufcpy:
79                         if (myisspace(c)) {
80                                 state = st_wordstart;
81                         } else {
82                                 if (len < bufsize-1)
83                                         *bufptr++ = c;
84                                 len++;
85                         }
86                         break;
87                 }
88         }
89
90         if (bufsize)
91                 *bufptr = '\0';
92
93         return len;
94 }
95
96 /*
97  * Find a boolean option (like quiet,noapic,nosmp....)
98  *
99  * Returns the position of that option (starts counting with 1)
100  * or 0 on not found
101  */
102 int __cmdline_find_option_bool(unsigned long cmdline_ptr, const char *option)
103 {
104         addr_t cptr;
105         char c;
106         int pos = 0, wstart = 0;
107         const char *opptr = NULL;
108         enum {
109                 st_wordstart,   /* Start of word/after whitespace */
110                 st_wordcmp,     /* Comparing this word */
111                 st_wordskip,    /* Miscompare, skip */
112         } state = st_wordstart;
113
114         if (!cmdline_ptr)
115                 return -1;      /* No command line */
116
117         cptr = cmdline_ptr & 0xf;
118         set_fs(cmdline_ptr >> 4);
119
120         while (cptr < 0x10000) {
121                 c = rdfs8(cptr++);
122                 pos++;
123
124                 switch (state) {
125                 case st_wordstart:
126                         if (!c)
127                                 return 0;
128                         else if (myisspace(c))
129                                 break;
130
131                         state = st_wordcmp;
132                         opptr = option;
133                         wstart = pos;
134                         /* fall through */
135
136                 case st_wordcmp:
137                         if (!*opptr)
138                                 if (!c || myisspace(c))
139                                         return wstart;
140                                 else
141                                         state = st_wordskip;
142                         else if (!c)
143                                 return 0;
144                         else if (c != *opptr++)
145                                 state = st_wordskip;
146                         break;
147
148                 case st_wordskip:
149                         if (!c)
150                                 return 0;
151                         else if (myisspace(c))
152                                 state = st_wordstart;
153                         break;
154                 }
155         }
156
157         return 0;       /* Buffer overrun */
158 }