Print this page
PANKOVs restructure
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/intel/io/acpica/master_ops.c
+++ new/usr/src/uts/intel/io/acpica/master_ops.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
↓ open down ↓ |
10 lines elided |
↑ open up ↑ |
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 +
21 22 /*
22 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
23 25 */
24 26
25 27 #include <sys/kobj.h>
26 28 #include <sys/kobj_lex.h>
27 29 #include <sys/ddi.h>
28 30 #include <sys/sunddi.h>
29 31 #include <sys/sunndi.h>
30 -#include <sys/acpi/acpi.h>
32 +
33 +#include <acpica/include/acpi.h>
31 34 #include <sys/acpica.h>
32 35
33 36 #define masterfile "/boot/solaris/devicedb/master"
34 37
35 38 /*
36 39 * Internal definitions
37 40 */
38 41
39 42 typedef enum {
40 43 MF_UNEXPECTED = -1,
41 44 MF_IDENT,
42 45 MF_STRING,
43 46 MF_EOF,
44 47 MF_NEWLINE,
45 48 MF_EQUALS,
46 49 MF_BIT_OR
47 50 } mftoken_t;
48 51
49 52 typedef enum {
50 53 MF_INIT,
51 54 MF_DEVID,
52 55 MF_NAME,
53 56 MF_DEVTYPE,
54 57 MF_BUSTYPE,
55 58 MF_BEFNAME,
56 59 MF_DESCRIPTION,
57 60 MF_PROPNAME,
58 61 MF_PROPASSIGN,
59 62 MF_PROPVAL,
60 63 MF_VERSION_DONE,
61 64 MF_VALID_DONE,
62 65 MF_ERROR_DONE
63 66 } mfparse_t;
64 67
65 68
66 69 static master_rec_t *master_list = NULL;
67 70
68 71 device_id_t *
69 72 mf_alloc_device_id()
70 73 {
71 74 return ((device_id_t *)kmem_zalloc(sizeof (device_id_t), KM_SLEEP));
72 75 }
73 76
74 77 void
75 78 mf_free_device_id(device_id_t *d)
76 79 {
77 80 if (d->id != NULL)
78 81 strfree(d->id);
79 82
80 83 kmem_free(d, sizeof (device_id_t));
81 84 }
82 85
83 86 static property_t *
84 87 mf_alloc_property()
85 88 {
86 89 return ((property_t *)kmem_zalloc(sizeof (property_t), KM_SLEEP));
87 90 }
88 91
89 92 static void
90 93 mf_free_property(property_t *p)
91 94 {
92 95 if (p->name != NULL)
93 96 strfree(p->name);
94 97
95 98 if (p->value != NULL)
96 99 strfree(p->value);
97 100
98 101 kmem_free(p, sizeof (property_t));
99 102 }
100 103
101 104 static master_rec_t *
102 105 mf_alloc_master_rec()
103 106 {
104 107 return ((master_rec_t *)kmem_zalloc(sizeof (master_rec_t), KM_SLEEP));
105 108 }
106 109
107 110 static void
108 111 mf_free_master_rec(master_rec_t *m)
109 112 {
110 113 device_id_t *d;
111 114 property_t *p;
112 115
113 116 if (m->name != NULL)
114 117 strfree(m->name);
115 118
116 119 if (m->description != NULL)
117 120 strfree(m->description);
118 121
119 122 d = m->device_ids;
120 123 while (d != NULL) {
121 124 device_id_t *next;
122 125
123 126 next = d->next;
124 127 mf_free_device_id(d);
125 128 d = next;
126 129 }
127 130
128 131 p = m->properties;
129 132 while (p != NULL) {
130 133 property_t *next;
131 134
132 135 next = p->next;
133 136 mf_free_property(p);
134 137 p = next;
135 138 }
136 139
137 140 kmem_free(m, sizeof (master_rec_t));
138 141 }
139 142
140 143 void
141 144 free_master_data()
142 145 {
143 146 master_rec_t *m;
144 147
145 148 m = master_list;
146 149 while (m != NULL) {
147 150 master_rec_t *next;
148 151
149 152 next = m->next;
150 153 mf_free_master_rec(m);
151 154 m = next;
152 155 }
153 156 master_list = NULL;
154 157 }
155 158
156 159 /*
157 160 * Unfortunately, kobj_lex() is too sophisticated for our needs
158 161 */
159 162 static mftoken_t
160 163 mf_lex(struct _buf *file, char *val, size_t size)
161 164 {
162 165 char *cp;
163 166 int ch, badquote;
164 167 size_t remain;
165 168 mftoken_t token = MF_UNEXPECTED;
166 169
167 170 if (size < 2)
168 171 return (token); /* MF_UNEXPECTED */
169 172
170 173 cp = val;
171 174
172 175 /* skip leading whitespace */
173 176 while ((ch = kobj_getc(file)) == ' ' || ch == '\t')
174 177 ;
175 178
176 179 /* strip comments */
177 180 if (ch == '#') {
178 181 while ((ch = kobj_getc(file)) != '\n' && ch != '\r' &&
179 182 ch != -1)
180 183 ;
181 184 }
182 185
183 186 remain = size - 1;
184 187 *cp++ = (char)ch;
185 188 switch (ch) {
186 189 case -1:
187 190 token = MF_EOF;
188 191 break;
189 192 case '\n':
190 193 case '\r':
191 194 token = MF_NEWLINE;
192 195 break;
193 196 case '=':
194 197 token = MF_EQUALS;
195 198 break;
196 199 case '|':
197 200 token = MF_BIT_OR;
198 201 break;
199 202 case '"':
200 203 remain++;
201 204 cp--;
202 205 badquote = 0;
203 206 while (!badquote && (ch = kobj_getc(file)) != '"') {
204 207 switch (ch) {
205 208 case '\n':
206 209 case -1:
207 210 remain = size - 1;
208 211 cp = val;
209 212 *cp++ = '\n';
210 213 badquote = 1;
211 214 /* since we consumed the newline/EOF */
212 215 (void) kobj_ungetc(file);
213 216 break;
214 217 default:
215 218 if (--remain == 0) {
216 219 token = MF_UNEXPECTED;
217 220 goto out;
218 221 }
219 222 *cp++ = (char)ch;
220 223 break;
221 224 }
222 225 }
223 226 token = MF_STRING;
224 227 break;
225 228 default:
226 229 do {
227 230 if (--remain == 0) {
228 231 token = MF_UNEXPECTED;
229 232 break;
230 233 }
231 234
232 235 token = MF_IDENT;
233 236 *cp++ = (char)(ch = kobj_getc(file));
234 237
235 238 /* if terminating character, break out */
236 239 if ((ch == -1) || (ch == ' ') || (ch == '\t') ||
237 240 (ch == '\n') || (ch == '\r') || (ch == '=') ||
238 241 (ch == '|')) {
239 242 (void) kobj_ungetc(file);
240 243 remain++;
241 244 cp--;
242 245 break;
243 246 }
244 247
245 248 if ((ch == '#') || (ch == '"'))
246 249 token = MF_UNEXPECTED;
247 250 } while (token != MF_UNEXPECTED);
248 251 break;
249 252 }
250 253 out:
251 254 *cp = '\0';
252 255
253 256 return (token);
254 257 }
255 258
256 259 static master_rec_t *
257 260 get_line(struct _buf *file)
258 261 {
259 262 master_rec_t *m = NULL;
260 263 device_id_t *d = NULL;
261 264 property_t *p = NULL;
262 265 mftoken_t token;
263 266 char tokval[MAXPATHLEN];
264 267 mfparse_t parse_state;
265 268
266 269 parse_state = MF_INIT;
267 270 token = mf_lex(file, tokval, sizeof (tokval));
268 271 while (token != MF_EOF) {
269 272 switch (parse_state) {
270 273 case MF_INIT:
271 274 m = mf_alloc_master_rec();
272 275 parse_state = MF_DEVID;
273 276 /*FALLTHROUGH*/
274 277 case MF_DEVID:
275 278 if (token == MF_IDENT) {
276 279 d = mf_alloc_device_id();
277 280 d->id = strdup(tokval);
278 281 d->next = m->device_ids;
279 282 m->device_ids = d;
280 283 parse_state = MF_NAME;
281 284 } else if (token != MF_NEWLINE)
282 285 parse_state = MF_ERROR_DONE;
283 286 break;
284 287 case MF_NAME:
285 288 if (token == MF_IDENT) {
286 289 m->name = strdup(tokval);
287 290 parse_state = MF_DEVTYPE;
288 291 } else if (token == MF_BIT_OR) {
289 292 parse_state = MF_DEVID;
290 293 } else
291 294 parse_state = MF_ERROR_DONE;
292 295 break;
293 296 case MF_DEVTYPE:
294 297 if (token == MF_IDENT) {
295 298 /* device_type not used */
296 299 parse_state = MF_BUSTYPE;
297 300 } else if (token == MF_NEWLINE) {
298 301 /* version line ignored */
299 302 parse_state = MF_VERSION_DONE;
300 303 } else
301 304 parse_state = MF_ERROR_DONE;
302 305 break;
303 306 case MF_BUSTYPE:
304 307 if (token == MF_IDENT) {
305 308 /* bus_type ignored */
306 309 parse_state = MF_BEFNAME;
307 310 } else
308 311 parse_state = MF_ERROR_DONE;
309 312 break;
310 313 case MF_BEFNAME:
311 314 if (token == MF_IDENT) {
312 315 /* realmode driver name ignored */
313 316 parse_state = MF_DESCRIPTION;
314 317 } else
315 318 parse_state = MF_ERROR_DONE;
316 319 break;
317 320 case MF_DESCRIPTION:
318 321 if (token == MF_STRING) {
319 322 m->description = strdup(tokval);
320 323 parse_state = MF_PROPNAME;
321 324 } else
322 325 parse_state = MF_ERROR_DONE;
323 326 break;
324 327 case MF_PROPNAME:
325 328 if (token == MF_IDENT) {
326 329 p = mf_alloc_property();
327 330 p->name = strdup(tokval);
328 331 parse_state = MF_PROPASSIGN;
329 332 } else if (token == MF_NEWLINE) {
330 333 parse_state = MF_VALID_DONE;
331 334 } else
332 335 parse_state = MF_ERROR_DONE;
333 336 break;
334 337 case MF_PROPASSIGN:
335 338 if (token == MF_EQUALS) {
336 339 parse_state = MF_PROPVAL;
337 340 } else
338 341 parse_state = MF_ERROR_DONE;
339 342 break;
340 343 case MF_PROPVAL:
341 344 if (token == MF_STRING || token == MF_IDENT) {
342 345 p->value = strdup(tokval);
343 346 p->next = m->properties;
344 347 /* delete properties which begin with '$' */
345 348 if (*p->name == '$') {
346 349 mf_free_property(p);
347 350 } else
348 351 m->properties = p;
349 352 p = NULL;
350 353 parse_state = MF_PROPNAME;
351 354 } else
352 355 parse_state = MF_ERROR_DONE;
353 356 break;
354 357 case MF_VERSION_DONE:
355 358 case MF_VALID_DONE:
356 359 case MF_ERROR_DONE:
357 360 /* terminating states handled outside switch() */
358 361 break;
359 362 }
360 363
361 364 if (parse_state == MF_VERSION_DONE) {
362 365 /* ignore version line */
363 366 mf_free_master_rec(m);
364 367 parse_state = MF_INIT;
365 368 } else if (parse_state == MF_VALID_DONE) {
366 369 /* valid line */
367 370 break;
368 371 } else if (parse_state == MF_ERROR_DONE) {
369 372 mf_free_master_rec(m);
370 373 if (p != NULL)
371 374 mf_free_property(p);
372 375 /*
373 376 * Error in master file. Should never happen
374 377 * since master file is not user-edited. Eat rest
375 378 * of line to attempt error recovery
376 379 */
377 380 cmn_err(CE_NOTE, "!error in %s", masterfile);
378 381 while (token != MF_NEWLINE && token != MF_EOF)
379 382 token = mf_lex(file, tokval, sizeof (tokval));
380 383 parse_state = MF_INIT;
381 384 continue;
382 385 }
383 386
384 387 token = mf_lex(file, tokval, sizeof (tokval));
385 388 }
386 389
387 390 return (m);
388 391 }
389 392
390 393 void
391 394 process_master_file()
392 395 {
393 396 struct _buf *file;
394 397 master_rec_t *m;
395 398
396 399 if ((file = kobj_open_file(masterfile)) == (struct _buf *)-1) {
397 400 cmn_err(CE_WARN, "!cannot open master file: %s", masterfile);
398 401 return;
399 402 }
400 403
401 404 while ((m = get_line(file)) != NULL) {
402 405 m->next = master_list;
403 406 master_list = m;
404 407 }
405 408
406 409 kobj_close_file(file);
407 410 }
408 411
409 412 /*
410 413 * Return the first master file record found matching pnpid list
411 414 */
412 415 const master_rec_t *
413 416 master_file_lookup(device_id_t *pnpid)
414 417 {
415 418 master_rec_t *m;
416 419 device_id_t *d;
417 420
418 421 while (pnpid != NULL) {
419 422 m = master_list;
420 423 while (m != NULL) {
421 424 d = m->device_ids;
422 425 while (d != NULL) {
423 426 if (strcmp(pnpid->id, d->id) == 0)
424 427 return (m);
425 428 d = d->next;
426 429 }
427 430 m = m->next;
428 431 }
429 432 pnpid = pnpid->next;
430 433 }
431 434
432 435 return (NULL);
433 436 }
↓ open down ↓ |
393 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX