2 * Copyright 2003 Digi International (www.digi.com)
3 * Scott H Kilau <Scott_Kilau at digi dot com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
12 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13 * PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE!
22 * This is shared code between Digi's CVS archive and the
23 * Linux Kernel sources.
24 * Changing the source just for reformatting needlessly breaks
25 * our CVS diff history.
27 * Send any bug fixes/changes to: Eng.Linux at digi dot com.
31 *****************************************************************************
33 * dgap_parse.c - Parses the configuration information from the input file.
35 * $Id: dgap_parse.c,v 1.1 2009/10/23 14:01:57 markh Exp $
38 #include <linux/kernel.h>
39 #include <linux/version.h>
40 #include <linux/ctype.h>
41 #include <linux/slab.h>
43 #include "dgap_types.h"
44 #include "dgap_fep5.h"
45 #include "dgap_driver.h"
46 #include "dgap_conf.h"
50 * Function prototypes.
52 static int dgap_gettok(char **in, struct cnode *p);
53 static char *dgap_getword(char **in);
54 static char *dgap_savestring(char *s);
55 static struct cnode *dgap_newnode(int t);
56 static int dgap_checknode(struct cnode *p);
57 static void dgap_err(char *s);
60 * Our needed internal static variables...
62 static struct cnode dgap_head;
64 static char dgap_cword[MAXCWORD];
71 static struct toklist dgap_tlist[] = {
72 { BEGIN, "config_begin" },
73 { END, "config_end" },
75 { PCX, "Digi_AccelePort_C/X_PCI" }, /* C/X_PCI */
76 { PEPC, "Digi_AccelePort_EPC/X_PCI" }, /* EPC/X_PCI */
77 { PPCM, "Digi_AccelePort_Xem_PCI" }, /* PCI/Xem */
78 { APORT2_920P, "Digi_AccelePort_2r_920_PCI" },
79 { APORT4_920P, "Digi_AccelePort_4r_920_PCI" },
80 { APORT8_920P, "Digi_AccelePort_8r_920_PCI" },
81 { PAPORT4, "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
82 { PAPORT8, "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
84 { PCIINFO, "pciinfo" },
87 { CONC, "concentrator" },
97 { CONNECT, "connect" },
100 { CUSTOM, "Custom" },
106 { NPORTS, "nports" },
111 { ALTPIN, "altpin" },
112 { USEINTR, "useintr" },
113 { TTSIZ, "ttysize" },
115 { BSSIZ, "boardsize" },
116 { UNTSIZ, "schedsize" },
117 { F2SIZ, "f2200size" },
118 { VPSIZ, "vpixsize" },
124 * Parse a configuration file read into memory as a string.
126 int dgap_parsefile(char **in, int Remove)
128 struct cnode *p, *brd, *line, *conc;
130 char *s = NULL, *s2 = NULL;
134 brd = line = conc = NULL;
136 /* perhaps we are adding to an existing list? */
137 while (p->next != NULL) {
141 /* file must start with a BEGIN */
142 while ( (rc = dgap_gettok(in,p)) != BEGIN ) {
144 dgap_err("unexpected EOF");
150 rc = dgap_gettok(in,p);
152 dgap_err("unexpected EOF");
158 dgap_err("unexpected end of file");
161 case BEGIN: /* should only be 1 begin */
162 dgap_err("unexpected config_begin\n");
168 case BOARD: /* board info */
169 if (dgap_checknode(p))
171 if ( (p->next = dgap_newnode(BNODE)) == NULL ) {
172 dgap_err("out of memory");
177 p->u.board.status = dgap_savestring("No");
183 case APORT2_920P: /* AccelePort_4 */
184 if (p->type != BNODE) {
185 dgap_err("unexpected Digi_2r_920 string");
188 p->u.board.type = APORT2_920P;
189 p->u.board.v_type = 1;
190 DPR_INIT(("Adding Digi_2r_920 PCI to config...\n"));
193 case APORT4_920P: /* AccelePort_4 */
194 if (p->type != BNODE) {
195 dgap_err("unexpected Digi_4r_920 string");
198 p->u.board.type = APORT4_920P;
199 p->u.board.v_type = 1;
200 DPR_INIT(("Adding Digi_4r_920 PCI to config...\n"));
203 case APORT8_920P: /* AccelePort_8 */
204 if (p->type != BNODE) {
205 dgap_err("unexpected Digi_8r_920 string");
208 p->u.board.type = APORT8_920P;
209 p->u.board.v_type = 1;
210 DPR_INIT(("Adding Digi_8r_920 PCI to config...\n"));
213 case PAPORT4: /* AccelePort_4 PCI */
214 if (p->type != BNODE) {
215 dgap_err("unexpected Digi_4r(PCI) string");
218 p->u.board.type = PAPORT4;
219 p->u.board.v_type = 1;
220 DPR_INIT(("Adding Digi_4r PCI to config...\n"));
223 case PAPORT8: /* AccelePort_8 PCI */
224 if (p->type != BNODE) {
225 dgap_err("unexpected Digi_8r string");
228 p->u.board.type = PAPORT8;
229 p->u.board.v_type = 1;
230 DPR_INIT(("Adding Digi_8r PCI to config...\n"));
233 case PCX: /* PCI C/X */
234 if (p->type != BNODE) {
235 dgap_err("unexpected Digi_C/X_(PCI) string");
238 p->u.board.type = PCX;
239 p->u.board.v_type = 1;
240 p->u.board.conc1 = 0;
241 p->u.board.conc2 = 0;
242 p->u.board.module1 = 0;
243 p->u.board.module2 = 0;
244 DPR_INIT(("Adding PCI C/X to config...\n"));
247 case PEPC: /* PCI EPC/X */
248 if (p->type != BNODE) {
249 dgap_err("unexpected \"Digi_EPC/X_(PCI)\" string");
252 p->u.board.type = PEPC;
253 p->u.board.v_type = 1;
254 p->u.board.conc1 = 0;
255 p->u.board.conc2 = 0;
256 p->u.board.module1 = 0;
257 p->u.board.module2 = 0;
258 DPR_INIT(("Adding PCI EPC/X to config...\n"));
261 case PPCM: /* PCI/Xem */
262 if (p->type != BNODE) {
263 dgap_err("unexpected PCI/Xem string");
266 p->u.board.type = PPCM;
267 p->u.board.v_type = 1;
268 p->u.board.conc1 = 0;
269 p->u.board.conc2 = 0;
270 DPR_INIT(("Adding PCI XEM to config...\n"));
273 case IO: /* i/o port */
274 if (p->type != BNODE) {
275 dgap_err("IO port only vaild for boards");
278 s = dgap_getword(in);
280 dgap_err("unexpected end of file");
283 p->u.board.portstr = dgap_savestring(s);
284 p->u.board.port = (short)simple_strtol(s, &s2, 0);
285 if ((short)strlen(s) > (short)(s2 - s)) {
286 dgap_err("bad number for IO port");
289 p->u.board.v_port = 1;
290 DPR_INIT(("Adding IO (%s) to config...\n", s));
293 case MEM: /* memory address */
294 if (p->type != BNODE) {
295 dgap_err("memory address only vaild for boards");
298 s = dgap_getword(in);
300 dgap_err("unexpected end of file");
303 p->u.board.addrstr = dgap_savestring(s);
304 p->u.board.addr = simple_strtoul(s, &s2, 0);
305 if ((int)strlen(s) > (int)(s2 - s)) {
306 dgap_err("bad number for memory address");
309 p->u.board.v_addr = 1;
310 DPR_INIT(("Adding MEM (%s) to config...\n", s));
313 case PCIINFO: /* pci information */
314 if (p->type != BNODE) {
315 dgap_err("memory address only vaild for boards");
318 s = dgap_getword(in);
320 dgap_err("unexpected end of file");
323 p->u.board.pcibusstr = dgap_savestring(s);
324 p->u.board.pcibus = simple_strtoul(s, &s2, 0);
325 if ((int)strlen(s) > (int)(s2 - s)) {
326 dgap_err("bad number for pci bus");
329 p->u.board.v_pcibus = 1;
330 s = dgap_getword(in);
332 dgap_err("unexpected end of file");
335 p->u.board.pcislotstr = dgap_savestring(s);
336 p->u.board.pcislot = simple_strtoul(s, &s2, 0);
337 if ((int)strlen(s) > (int)(s2 - s)) {
338 dgap_err("bad number for pci slot");
341 p->u.board.v_pcislot = 1;
343 DPR_INIT(("Adding PCIINFO (%s %s) to config...\n", p->u.board.pcibusstr,
344 p->u.board.pcislotstr));
348 if (p->type != BNODE) {
349 dgap_err("install method only vaild for boards");
352 s = dgap_getword(in);
354 dgap_err("unexpected end of file");
357 p->u.board.method = dgap_savestring(s);
358 p->u.board.v_method = 1;
359 DPR_INIT(("Adding METHOD (%s) to config...\n", s));
363 if (p->type != BNODE) {
364 dgap_err("config status only vaild for boards");
367 s = dgap_getword(in);
369 dgap_err("unexpected end of file");
372 p->u.board.status = dgap_savestring(s);
373 DPR_INIT(("Adding STATUS (%s) to config...\n", s));
376 case NPORTS: /* number of ports */
377 if (p->type == BNODE) {
378 s = dgap_getword(in);
380 dgap_err("unexpected end of file");
383 p->u.board.nport = (char)simple_strtol(s, &s2, 0);
384 if ((int)strlen(s) > (int)(s2 - s)) {
385 dgap_err("bad number for number of ports");
388 p->u.board.v_nport = 1;
389 } else if (p->type == CNODE) {
390 s = dgap_getword(in);
392 dgap_err("unexpected end of file");
395 p->u.conc.nport = (char)simple_strtol(s, &s2, 0);
396 if ((int)strlen(s) > (int)(s2 - s)) {
397 dgap_err("bad number for number of ports");
400 p->u.conc.v_nport = 1;
401 } else if (p->type == MNODE) {
402 s = dgap_getword(in);
404 dgap_err("unexpected end of file");
407 p->u.module.nport = (char)simple_strtol(s, &s2, 0);
408 if ((int)strlen(s) > (int)(s2 - s)) {
409 dgap_err("bad number for number of ports");
412 p->u.module.v_nport = 1;
414 dgap_err("nports only valid for concentrators or modules");
417 DPR_INIT(("Adding NPORTS (%s) to config...\n", s));
420 case ID: /* letter ID used in tty name */
421 s = dgap_getword(in);
423 dgap_err("unexpected end of file");
427 p->u.board.status = dgap_savestring(s);
429 if (p->type == CNODE) {
430 p->u.conc.id = dgap_savestring(s);
432 } else if (p->type == MNODE) {
433 p->u.module.id = dgap_savestring(s);
434 p->u.module.v_id = 1;
436 dgap_err("id only valid for concentrators or modules");
439 DPR_INIT(("Adding ID (%s) to config...\n", s));
442 case STARTO: /* start offset of ID */
443 if (p->type == BNODE) {
444 s = dgap_getword(in);
446 dgap_err("unexpected end of file");
449 p->u.board.start = simple_strtol(s, &s2, 0);
450 if ((int)strlen(s) > (int)(s2 - s)) {
451 dgap_err("bad number for start of tty count");
454 p->u.board.v_start = 1;
455 } else if (p->type == CNODE) {
456 s = dgap_getword(in);
458 dgap_err("unexpected end of file");
461 p->u.conc.start = simple_strtol(s, &s2, 0);
462 if ((int)strlen(s) > (int)(s2 - s)) {
463 dgap_err("bad number for start of tty count");
466 p->u.conc.v_start = 1;
467 } else if (p->type == MNODE) {
468 s = dgap_getword(in);
470 dgap_err("unexpected end of file");
473 p->u.module.start = simple_strtol(s, &s2, 0);
474 if ((int)strlen(s) > (int)(s2 - s)) {
475 dgap_err("bad number for start of tty count");
478 p->u.module.v_start = 1;
480 dgap_err("start only valid for concentrators or modules");
483 DPR_INIT(("Adding START (%s) to config...\n", s));
486 case TTYN: /* tty name prefix */
487 if (dgap_checknode(p))
489 if ( (p->next = dgap_newnode(TNODE)) == NULL ) {
490 dgap_err("out of memory");
494 if ( (s = dgap_getword(in)) == NULL ) {
495 dgap_err("unexpeced end of file");
498 if ( (p->u.ttyname = dgap_savestring(s)) == NULL ) {
499 dgap_err("out of memory");
502 DPR_INIT(("Adding TTY (%s) to config...\n", s));
505 case CU: /* cu name prefix */
506 if (dgap_checknode(p))
508 if ( (p->next = dgap_newnode(CUNODE)) == NULL ) {
509 dgap_err("out of memory");
513 if ( (s = dgap_getword(in)) == NULL ) {
514 dgap_err("unexpeced end of file");
517 if ( (p->u.cuname = dgap_savestring(s)) == NULL ) {
518 dgap_err("out of memory");
521 DPR_INIT(("Adding CU (%s) to config...\n", s));
524 case LINE: /* line information */
525 if (dgap_checknode(p))
528 dgap_err("must specify board before line info");
531 switch (brd->u.board.type) {
533 dgap_err("line not vaild for PC/em");
536 if ( (p->next = dgap_newnode(LNODE)) == NULL ) {
537 dgap_err("out of memory");
544 DPR_INIT(("Adding LINE to config...\n"));
547 case CONC: /* concentrator information */
548 if (dgap_checknode(p))
551 dgap_err("must specify line info before concentrator");
554 if ( (p->next = dgap_newnode(CNODE)) == NULL ) {
555 dgap_err("out of memory");
561 brd->u.board.conc2++;
563 brd->u.board.conc1++;
565 DPR_INIT(("Adding CONC to config...\n"));
568 case CX: /* c/x type concentrator */
569 if (p->type != CNODE) {
570 dgap_err("cx only valid for concentrators");
574 p->u.conc.v_type = 1;
575 DPR_INIT(("Adding CX to config...\n"));
578 case EPC: /* epc type concentrator */
579 if (p->type != CNODE) {
580 dgap_err("cx only valid for concentrators");
583 p->u.conc.type = EPC;
584 p->u.conc.v_type = 1;
585 DPR_INIT(("Adding EPC to config...\n"));
588 case MOD: /* EBI module */
589 if (dgap_checknode(p))
592 dgap_err("must specify board info before EBI modules");
595 switch (brd->u.board.type) {
601 dgap_err("must specify concentrator info before EBI module");
605 if ( (p->next = dgap_newnode(MNODE)) == NULL ) {
606 dgap_err("out of memory");
611 brd->u.board.module2++;
613 brd->u.board.module1++;
615 DPR_INIT(("Adding MOD to config...\n"));
618 case PORTS: /* ports type EBI module */
619 if (p->type != MNODE) {
620 dgap_err("ports only valid for EBI modules");
623 p->u.module.type = PORTS;
624 p->u.module.v_type = 1;
625 DPR_INIT(("Adding PORTS to config...\n"));
628 case MODEM: /* ports type EBI module */
629 if (p->type != MNODE) {
630 dgap_err("modem only valid for modem modules");
633 p->u.module.type = MODEM;
634 p->u.module.v_type = 1;
635 DPR_INIT(("Adding MODEM to config...\n"));
639 if (p->type == LNODE) {
640 if ((s = dgap_getword(in)) == NULL) {
641 dgap_err("unexpected end of file");
644 p->u.line.cable = dgap_savestring(s);
645 p->u.line.v_cable = 1;
647 DPR_INIT(("Adding CABLE (%s) to config...\n", s));
650 case SPEED: /* sync line speed indication */
651 if (p->type == LNODE) {
652 s = dgap_getword(in);
654 dgap_err("unexpected end of file");
657 p->u.line.speed = (char)simple_strtol(s, &s2, 0);
658 if ((short)strlen(s) > (short)(s2 - s)) {
659 dgap_err("bad number for line speed");
662 p->u.line.v_speed = 1;
663 } else if (p->type == CNODE) {
664 s = dgap_getword(in);
666 dgap_err("unexpected end of file");
669 p->u.conc.speed = (char)simple_strtol(s, &s2, 0);
670 if ((short)strlen(s) > (short)(s2 - s)) {
671 dgap_err("bad number for line speed");
674 p->u.conc.v_speed = 1;
676 dgap_err("speed valid only for lines or concentrators.");
679 DPR_INIT(("Adding SPEED (%s) to config...\n", s));
683 if (p->type == CNODE) {
684 if ((s = dgap_getword(in)) == NULL) {
685 dgap_err("unexpected end of file");
688 p->u.conc.connect = dgap_savestring(s);
689 p->u.conc.v_connect = 1;
691 DPR_INIT(("Adding CONNECT (%s) to config...\n", s));
693 case PRINT: /* transparent print name prefix */
694 if (dgap_checknode(p))
696 if ( (p->next = dgap_newnode(PNODE)) == NULL ) {
697 dgap_err("out of memory");
701 if ( (s = dgap_getword(in)) == NULL ) {
702 dgap_err("unexpeced end of file");
705 if ( (p->u.printname = dgap_savestring(s)) == NULL ) {
706 dgap_err("out of memory");
709 DPR_INIT(("Adding PRINT (%s) to config...\n", s));
712 case CMAJOR: /* major number */
713 if (dgap_checknode(p))
715 if ( (p->next = dgap_newnode(JNODE)) == NULL ) {
716 dgap_err("out of memory");
720 s = dgap_getword(in);
722 dgap_err("unexpected end of file");
725 p->u.majornumber = simple_strtol(s, &s2, 0);
726 if ((int)strlen(s) > (int)(s2 - s)) {
727 dgap_err("bad number for major number");
730 DPR_INIT(("Adding CMAJOR (%s) to config...\n", s));
733 case ALTPIN: /* altpin setting */
734 if (dgap_checknode(p))
736 if ( (p->next = dgap_newnode(ANODE)) == NULL ) {
737 dgap_err("out of memory");
741 s = dgap_getword(in);
743 dgap_err("unexpected end of file");
746 p->u.altpin = simple_strtol(s, &s2, 0);
747 if ((int)strlen(s) > (int)(s2 - s)) {
748 dgap_err("bad number for altpin");
751 DPR_INIT(("Adding ALTPIN (%s) to config...\n", s));
754 case USEINTR: /* enable interrupt setting */
755 if (dgap_checknode(p))
757 if ( (p->next = dgap_newnode(INTRNODE)) == NULL ) {
758 dgap_err("out of memory");
762 s = dgap_getword(in);
764 dgap_err("unexpected end of file");
767 p->u.useintr = simple_strtol(s, &s2, 0);
768 if ((int)strlen(s) > (int)(s2 - s)) {
769 dgap_err("bad number for useintr");
772 DPR_INIT(("Adding USEINTR (%s) to config...\n", s));
775 case TTSIZ: /* size of tty structure */
776 if (dgap_checknode(p))
778 if ( (p->next = dgap_newnode(TSNODE)) == NULL ) {
779 dgap_err("out of memory");
783 s = dgap_getword(in);
785 dgap_err("unexpected end of file");
788 p->u.ttysize = simple_strtol(s, &s2, 0);
789 if ((int)strlen(s) > (int)(s2 - s)) {
790 dgap_err("bad number for ttysize");
793 DPR_INIT(("Adding TTSIZ (%s) to config...\n", s));
796 case CHSIZ: /* channel structure size */
797 if (dgap_checknode(p))
799 if ( (p->next = dgap_newnode(CSNODE)) == NULL ) {
800 dgap_err("out of memory");
804 s = dgap_getword(in);
806 dgap_err("unexpected end of file");
809 p->u.chsize = simple_strtol(s, &s2, 0);
810 if ((int)strlen(s) > (int)(s2 - s)) {
811 dgap_err("bad number for chsize");
814 DPR_INIT(("Adding CHSIZE (%s) to config...\n", s));
817 case BSSIZ: /* board structure size */
818 if (dgap_checknode(p))
820 if ( (p->next = dgap_newnode(BSNODE)) == NULL ) {
821 dgap_err("out of memory");
825 s = dgap_getword(in);
827 dgap_err("unexpected end of file");
830 p->u.bssize = simple_strtol(s, &s2, 0);
831 if ((int)strlen(s) > (int)(s2 - s)) {
832 dgap_err("bad number for bssize");
835 DPR_INIT(("Adding BSSIZ (%s) to config...\n", s));
838 case UNTSIZ: /* sched structure size */
839 if (dgap_checknode(p))
841 if ( (p->next = dgap_newnode(USNODE)) == NULL ) {
842 dgap_err("out of memory");
846 s = dgap_getword(in);
848 dgap_err("unexpected end of file");
851 p->u.unsize = simple_strtol(s, &s2, 0);
852 if ((int)strlen(s) > (int)(s2 - s)) {
853 dgap_err("bad number for schedsize");
856 DPR_INIT(("Adding UNTSIZ (%s) to config...\n", s));
859 case F2SIZ: /* f2200 structure size */
860 if (dgap_checknode(p))
862 if ( (p->next = dgap_newnode(FSNODE)) == NULL ) {
863 dgap_err("out of memory");
867 s = dgap_getword(in);
869 dgap_err("unexpected end of file");
872 p->u.f2size = simple_strtol(s, &s2, 0);
873 if ((int)strlen(s) > (int)(s2 - s)) {
874 dgap_err("bad number for f2200size");
877 DPR_INIT(("Adding F2SIZ (%s) to config...\n", s));
880 case VPSIZ: /* vpix structure size */
881 if (dgap_checknode(p))
883 if ( (p->next = dgap_newnode(VSNODE)) == NULL ) {
884 dgap_err("out of memory");
888 s = dgap_getword(in);
890 dgap_err("unexpected end of file");
893 p->u.vpixsize = simple_strtol(s, &s2, 0);
894 if ((int)strlen(s) > (int)(s2 - s)) {
895 dgap_err("bad number for vpixsize");
898 DPR_INIT(("Adding VPSIZ (%s) to config...\n", s));
906 * dgap_sindex: much like index(), but it looks for a match of any character in
907 * the group, and returns that position. If the first character is a ^, then
908 * this will match the first occurence not in that group.
910 static char *dgap_sindex (char *string, char *group)
914 if (!string || !group)
915 return (char *) NULL;
919 for (; *string; string++) {
920 for (ptr = group; *ptr; ptr++) {
929 for (; *string; string++) {
930 for (ptr = group; *ptr; ptr++) {
937 return (char *) NULL;
942 * Get a token from the input file; return 0 if end of file is reached
944 static int dgap_gettok(char **in, struct cnode *p)
949 if (strstr(dgap_cword, "boar")) {
950 w = dgap_getword(in);
951 snprintf(dgap_cword, MAXCWORD, "%s", w);
952 for (t = dgap_tlist; t->token != 0; t++) {
953 if ( !strcmp(w, t->string)) {
957 dgap_err("board !!type not specified");
961 while ( (w = dgap_getword(in)) != NULL ) {
962 snprintf(dgap_cword, MAXCWORD, "%s", w);
963 for (t = dgap_tlist; t->token != 0; t++) {
964 if ( !strcmp(w, t->string) )
974 * get a word from the input stream, also keep track of current line number.
975 * words are separated by whitespace.
977 static char *dgap_getword(char **in)
981 char *ptr = dgap_sindex(*in, " \t\n");
983 /* If no word found, return null */
987 /* Mark new location for our buffer */
991 /* Eat any extra spaces/tabs/newlines that might be present */
992 while (*in && **in && ((**in == ' ') || (**in == '\t') || (**in == '\n'))) {
1002 * print an error message, giving the line number in the file where
1003 * the error occurred.
1005 static void dgap_err(char *s)
1007 printk("DGAP: parse: %s\n", s);
1012 * allocate a new configuration node of type t
1014 static struct cnode *dgap_newnode(int t)
1017 if ( (n = (struct cnode *) kmalloc(sizeof(struct cnode ), GFP_ATOMIC) ) != NULL) {
1018 memset( (char *)n, 0, sizeof(struct cnode ) );
1026 * dgap_checknode: see if all the necessary info has been supplied for a node
1027 * before creating the next node.
1029 static int dgap_checknode(struct cnode *p)
1033 if (p->u.board.v_type == 0) {
1034 dgap_err("board type !not specified");
1041 if (p->u.line.v_speed == 0) {
1042 dgap_err("line speed not specified");
1048 if (p->u.conc.v_type == 0) {
1049 dgap_err("concentrator type not specified");
1052 if (p->u.conc.v_speed == 0) {
1053 dgap_err("concentrator line speed not specified");
1056 if (p->u.conc.v_nport == 0) {
1057 dgap_err("number of ports on concentrator not specified");
1060 if (p->u.conc.v_id == 0) {
1061 dgap_err("concentrator id letter not specified");
1067 if (p->u.module.v_type == 0) {
1068 dgap_err("EBI module type not specified");
1071 if (p->u.module.v_nport == 0) {
1072 dgap_err("number of ports on EBI module not specified");
1075 if (p->u.module.v_id == 0) {
1076 dgap_err("EBI module id letter not specified");
1085 * save a string somewhere
1087 static char *dgap_savestring(char *s)
1090 if ( (p = kmalloc(strlen(s) + 1, GFP_ATOMIC) ) != NULL) {
1098 * Given a board pointer, returns whether we should use interrupts or not.
1100 uint dgap_config_get_useintr(struct board_t *bd)
1102 struct cnode *p = NULL;
1107 for (p = bd->bd_config; p; p = p->next) {
1111 * check for pcxr types.
1113 return p->u.useintr;
1119 /* If not found, then don't turn on interrupts. */
1125 * Given a board pointer, returns whether we turn on altpin or not.
1127 uint dgap_config_get_altpin(struct board_t *bd)
1129 struct cnode *p = NULL;
1134 for (p = bd->bd_config; p; p = p->next) {
1138 * check for pcxr types.
1146 /* If not found, then don't turn on interrupts. */
1153 * Given a specific type of board, if found, detached link and
1154 * returns the first occurance in the list.
1156 struct cnode *dgap_find_config(int type, int bus, int slot)
1158 struct cnode *p, *prev = NULL, *prev2 = NULL, *found = NULL;
1162 while (p->next != NULL) {
1166 if (p->type == BNODE) {
1168 if (p->u.board.type == type) {
1170 if (p->u.board.v_pcibus && p->u.board.pcibus != bus) {
1171 DPR(("Found matching board, but wrong bus position. System says bus %d, we want bus %ld\n",
1172 bus, p->u.board.pcibus));
1175 if (p->u.board.v_pcislot && p->u.board.pcislot != slot) {
1176 DPR_INIT(("Found matching board, but wrong slot position. System says slot %d, we want slot %ld\n",
1177 slot, p->u.board.pcislot));
1181 DPR_INIT(("Matched type in config file\n"));
1185 * Keep walking thru the list till we find the next board.
1187 while (p->next != NULL) {
1190 if (p->type == BNODE) {
1193 * Mark the end of our 1 board chain of configs.
1198 * Link the "next" board to the previous board,
1199 * effectively "unlinking" our board from the main config.
1207 * It must be the last board in the list.
1218 * Given a board pointer, walks the config link, counting up
1219 * all ports user specified should be on the board.
1220 * (This does NOT mean they are all actually present right now tho)
1222 uint dgap_config_get_number_of_ports(struct board_t *bd)
1225 struct cnode *p = NULL;
1230 for (p = bd->bd_config; p; p = p->next) {
1235 * check for pcxr types.
1237 if (p->u.board.type > EPCFE)
1238 count += p->u.board.nport;
1241 count += p->u.conc.nport;
1244 count += p->u.module.nport;
1251 char *dgap_create_config_string(struct board_t *bd, char *string)
1254 struct cnode *p = NULL;
1255 struct cnode *q = NULL;
1263 for (p = bd->bd_config; p; p = p->next) {
1269 *ptr = p->u.line.speed;
1274 * Because the EPC/con concentrators can have EM modules
1275 * hanging off of them, we have to walk ahead in the list
1276 * and keep adding the number of ports on each EM to the config.
1279 speed = p->u.conc.speed;
1281 if ((q != NULL) && (q->type == MNODE) ) {
1282 *ptr = (p->u.conc.nport + 0x80);
1285 while ((q->next != NULL) && (q->next->type) == MNODE) {
1286 *ptr = (q->u.module.nport + 0x80);
1291 *ptr = q->u.module.nport;
1294 *ptr = p->u.conc.nport;
1310 char *dgap_get_config_letters(struct board_t *bd, char *string)
1314 struct cnode *cptr = NULL;
1316 int left = MAXTTYNAMELEN;
1322 for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
1324 if ((cptr->type == BNODE) &&
1325 ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
1326 (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
1327 (cptr->u.board.type == PAPORT8))) {
1332 if (cptr->type == TNODE && found == TRUE) {
1334 if (strstr(cptr->u.ttyname, "tty")) {
1335 ptr1 = cptr->u.ttyname;
1339 ptr1 = cptr->u.ttyname;
1342 len = snprintf(ptr, left, "%s", ptr1);
1350 if (cptr->type == CNODE) {
1351 if (cptr->u.conc.id) {
1352 len = snprintf(ptr, left, "%s", cptr->u.conc.id);
1360 if (cptr->type == MNODE) {
1361 if (cptr->u.module.id) {
1362 len = snprintf(ptr, left, "%s", cptr->u.module.id);