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/ctype.h>
40 #include <linux/slab.h>
42 #include "dgap_types.h"
43 #include "dgap_fep5.h"
44 #include "dgap_driver.h"
45 #include "dgap_conf.h"
49 * Function prototypes.
51 static int dgap_gettok(char **in, struct cnode *p);
52 static char *dgap_getword(char **in);
53 static char *dgap_savestring(char *s);
54 static struct cnode *dgap_newnode(int t);
55 static int dgap_checknode(struct cnode *p);
56 static void dgap_err(char *s);
59 * Our needed internal static variables...
61 static struct cnode dgap_head;
63 static char dgap_cword[MAXCWORD];
70 static struct toklist dgap_tlist[] = {
71 { BEGIN, "config_begin" },
72 { END, "config_end" },
74 { PCX, "Digi_AccelePort_C/X_PCI" }, /* C/X_PCI */
75 { PEPC, "Digi_AccelePort_EPC/X_PCI" }, /* EPC/X_PCI */
76 { PPCM, "Digi_AccelePort_Xem_PCI" }, /* PCI/Xem */
77 { APORT2_920P, "Digi_AccelePort_2r_920_PCI" },
78 { APORT4_920P, "Digi_AccelePort_4r_920_PCI" },
79 { APORT8_920P, "Digi_AccelePort_8r_920_PCI" },
80 { PAPORT4, "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
81 { PAPORT8, "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
83 { PCIINFO, "pciinfo" },
86 { CONC, "concentrator" },
96 { CONNECT, "connect" },
105 { NPORTS, "nports" },
110 { ALTPIN, "altpin" },
111 { USEINTR, "useintr" },
112 { TTSIZ, "ttysize" },
114 { BSSIZ, "boardsize" },
115 { UNTSIZ, "schedsize" },
116 { F2SIZ, "f2200size" },
117 { VPSIZ, "vpixsize" },
123 * Parse a configuration file read into memory as a string.
125 int dgap_parsefile(char **in, int Remove)
127 struct cnode *p, *brd, *line, *conc;
129 char *s = NULL, *s2 = NULL;
133 brd = line = conc = NULL;
135 /* perhaps we are adding to an existing list? */
136 while (p->next != NULL) {
140 /* file must start with a BEGIN */
141 while ( (rc = dgap_gettok(in,p)) != BEGIN ) {
143 dgap_err("unexpected EOF");
149 rc = dgap_gettok(in,p);
151 dgap_err("unexpected EOF");
157 dgap_err("unexpected end of file");
160 case BEGIN: /* should only be 1 begin */
161 dgap_err("unexpected config_begin\n");
167 case BOARD: /* board info */
168 if (dgap_checknode(p))
170 if ( (p->next = dgap_newnode(BNODE)) == NULL ) {
171 dgap_err("out of memory");
176 p->u.board.status = dgap_savestring("No");
182 case APORT2_920P: /* AccelePort_4 */
183 if (p->type != BNODE) {
184 dgap_err("unexpected Digi_2r_920 string");
187 p->u.board.type = APORT2_920P;
188 p->u.board.v_type = 1;
189 DPR_INIT(("Adding Digi_2r_920 PCI to config...\n"));
192 case APORT4_920P: /* AccelePort_4 */
193 if (p->type != BNODE) {
194 dgap_err("unexpected Digi_4r_920 string");
197 p->u.board.type = APORT4_920P;
198 p->u.board.v_type = 1;
199 DPR_INIT(("Adding Digi_4r_920 PCI to config...\n"));
202 case APORT8_920P: /* AccelePort_8 */
203 if (p->type != BNODE) {
204 dgap_err("unexpected Digi_8r_920 string");
207 p->u.board.type = APORT8_920P;
208 p->u.board.v_type = 1;
209 DPR_INIT(("Adding Digi_8r_920 PCI to config...\n"));
212 case PAPORT4: /* AccelePort_4 PCI */
213 if (p->type != BNODE) {
214 dgap_err("unexpected Digi_4r(PCI) string");
217 p->u.board.type = PAPORT4;
218 p->u.board.v_type = 1;
219 DPR_INIT(("Adding Digi_4r PCI to config...\n"));
222 case PAPORT8: /* AccelePort_8 PCI */
223 if (p->type != BNODE) {
224 dgap_err("unexpected Digi_8r string");
227 p->u.board.type = PAPORT8;
228 p->u.board.v_type = 1;
229 DPR_INIT(("Adding Digi_8r PCI to config...\n"));
232 case PCX: /* PCI C/X */
233 if (p->type != BNODE) {
234 dgap_err("unexpected Digi_C/X_(PCI) string");
237 p->u.board.type = PCX;
238 p->u.board.v_type = 1;
239 p->u.board.conc1 = 0;
240 p->u.board.conc2 = 0;
241 p->u.board.module1 = 0;
242 p->u.board.module2 = 0;
243 DPR_INIT(("Adding PCI C/X to config...\n"));
246 case PEPC: /* PCI EPC/X */
247 if (p->type != BNODE) {
248 dgap_err("unexpected \"Digi_EPC/X_(PCI)\" string");
251 p->u.board.type = PEPC;
252 p->u.board.v_type = 1;
253 p->u.board.conc1 = 0;
254 p->u.board.conc2 = 0;
255 p->u.board.module1 = 0;
256 p->u.board.module2 = 0;
257 DPR_INIT(("Adding PCI EPC/X to config...\n"));
260 case PPCM: /* PCI/Xem */
261 if (p->type != BNODE) {
262 dgap_err("unexpected PCI/Xem string");
265 p->u.board.type = PPCM;
266 p->u.board.v_type = 1;
267 p->u.board.conc1 = 0;
268 p->u.board.conc2 = 0;
269 DPR_INIT(("Adding PCI XEM to config...\n"));
272 case IO: /* i/o port */
273 if (p->type != BNODE) {
274 dgap_err("IO port only vaild for boards");
277 s = dgap_getword(in);
279 dgap_err("unexpected end of file");
282 p->u.board.portstr = dgap_savestring(s);
283 p->u.board.port = (short)simple_strtol(s, &s2, 0);
284 if ((short)strlen(s) > (short)(s2 - s)) {
285 dgap_err("bad number for IO port");
288 p->u.board.v_port = 1;
289 DPR_INIT(("Adding IO (%s) to config...\n", s));
292 case MEM: /* memory address */
293 if (p->type != BNODE) {
294 dgap_err("memory address only vaild for boards");
297 s = dgap_getword(in);
299 dgap_err("unexpected end of file");
302 p->u.board.addrstr = dgap_savestring(s);
303 p->u.board.addr = simple_strtoul(s, &s2, 0);
304 if ((int)strlen(s) > (int)(s2 - s)) {
305 dgap_err("bad number for memory address");
308 p->u.board.v_addr = 1;
309 DPR_INIT(("Adding MEM (%s) to config...\n", s));
312 case PCIINFO: /* pci information */
313 if (p->type != BNODE) {
314 dgap_err("memory address only vaild for boards");
317 s = dgap_getword(in);
319 dgap_err("unexpected end of file");
322 p->u.board.pcibusstr = dgap_savestring(s);
323 p->u.board.pcibus = simple_strtoul(s, &s2, 0);
324 if ((int)strlen(s) > (int)(s2 - s)) {
325 dgap_err("bad number for pci bus");
328 p->u.board.v_pcibus = 1;
329 s = dgap_getword(in);
331 dgap_err("unexpected end of file");
334 p->u.board.pcislotstr = dgap_savestring(s);
335 p->u.board.pcislot = simple_strtoul(s, &s2, 0);
336 if ((int)strlen(s) > (int)(s2 - s)) {
337 dgap_err("bad number for pci slot");
340 p->u.board.v_pcislot = 1;
342 DPR_INIT(("Adding PCIINFO (%s %s) to config...\n", p->u.board.pcibusstr,
343 p->u.board.pcislotstr));
347 if (p->type != BNODE) {
348 dgap_err("install method only vaild for boards");
351 s = dgap_getword(in);
353 dgap_err("unexpected end of file");
356 p->u.board.method = dgap_savestring(s);
357 p->u.board.v_method = 1;
358 DPR_INIT(("Adding METHOD (%s) to config...\n", s));
362 if (p->type != BNODE) {
363 dgap_err("config status only vaild for boards");
366 s = dgap_getword(in);
368 dgap_err("unexpected end of file");
371 p->u.board.status = dgap_savestring(s);
372 DPR_INIT(("Adding STATUS (%s) to config...\n", s));
375 case NPORTS: /* number of ports */
376 if (p->type == BNODE) {
377 s = dgap_getword(in);
379 dgap_err("unexpected end of file");
382 p->u.board.nport = (char)simple_strtol(s, &s2, 0);
383 if ((int)strlen(s) > (int)(s2 - s)) {
384 dgap_err("bad number for number of ports");
387 p->u.board.v_nport = 1;
388 } else if (p->type == CNODE) {
389 s = dgap_getword(in);
391 dgap_err("unexpected end of file");
394 p->u.conc.nport = (char)simple_strtol(s, &s2, 0);
395 if ((int)strlen(s) > (int)(s2 - s)) {
396 dgap_err("bad number for number of ports");
399 p->u.conc.v_nport = 1;
400 } else if (p->type == MNODE) {
401 s = dgap_getword(in);
403 dgap_err("unexpected end of file");
406 p->u.module.nport = (char)simple_strtol(s, &s2, 0);
407 if ((int)strlen(s) > (int)(s2 - s)) {
408 dgap_err("bad number for number of ports");
411 p->u.module.v_nport = 1;
413 dgap_err("nports only valid for concentrators or modules");
416 DPR_INIT(("Adding NPORTS (%s) to config...\n", s));
419 case ID: /* letter ID used in tty name */
420 s = dgap_getword(in);
422 dgap_err("unexpected end of file");
426 p->u.board.status = dgap_savestring(s);
428 if (p->type == CNODE) {
429 p->u.conc.id = dgap_savestring(s);
431 } else if (p->type == MNODE) {
432 p->u.module.id = dgap_savestring(s);
433 p->u.module.v_id = 1;
435 dgap_err("id only valid for concentrators or modules");
438 DPR_INIT(("Adding ID (%s) to config...\n", s));
441 case STARTO: /* start offset of ID */
442 if (p->type == BNODE) {
443 s = dgap_getword(in);
445 dgap_err("unexpected end of file");
448 p->u.board.start = simple_strtol(s, &s2, 0);
449 if ((int)strlen(s) > (int)(s2 - s)) {
450 dgap_err("bad number for start of tty count");
453 p->u.board.v_start = 1;
454 } else if (p->type == CNODE) {
455 s = dgap_getword(in);
457 dgap_err("unexpected end of file");
460 p->u.conc.start = simple_strtol(s, &s2, 0);
461 if ((int)strlen(s) > (int)(s2 - s)) {
462 dgap_err("bad number for start of tty count");
465 p->u.conc.v_start = 1;
466 } else if (p->type == MNODE) {
467 s = dgap_getword(in);
469 dgap_err("unexpected end of file");
472 p->u.module.start = simple_strtol(s, &s2, 0);
473 if ((int)strlen(s) > (int)(s2 - s)) {
474 dgap_err("bad number for start of tty count");
477 p->u.module.v_start = 1;
479 dgap_err("start only valid for concentrators or modules");
482 DPR_INIT(("Adding START (%s) to config...\n", s));
485 case TTYN: /* tty name prefix */
486 if (dgap_checknode(p))
488 if ( (p->next = dgap_newnode(TNODE)) == NULL ) {
489 dgap_err("out of memory");
493 if ( (s = dgap_getword(in)) == NULL ) {
494 dgap_err("unexpeced end of file");
497 if ( (p->u.ttyname = dgap_savestring(s)) == NULL ) {
498 dgap_err("out of memory");
501 DPR_INIT(("Adding TTY (%s) to config...\n", s));
504 case CU: /* cu name prefix */
505 if (dgap_checknode(p))
507 if ( (p->next = dgap_newnode(CUNODE)) == NULL ) {
508 dgap_err("out of memory");
512 if ( (s = dgap_getword(in)) == NULL ) {
513 dgap_err("unexpeced end of file");
516 if ( (p->u.cuname = dgap_savestring(s)) == NULL ) {
517 dgap_err("out of memory");
520 DPR_INIT(("Adding CU (%s) to config...\n", s));
523 case LINE: /* line information */
524 if (dgap_checknode(p))
527 dgap_err("must specify board before line info");
530 switch (brd->u.board.type) {
532 dgap_err("line not vaild for PC/em");
535 if ( (p->next = dgap_newnode(LNODE)) == NULL ) {
536 dgap_err("out of memory");
543 DPR_INIT(("Adding LINE to config...\n"));
546 case CONC: /* concentrator information */
547 if (dgap_checknode(p))
550 dgap_err("must specify line info before concentrator");
553 if ( (p->next = dgap_newnode(CNODE)) == NULL ) {
554 dgap_err("out of memory");
560 brd->u.board.conc2++;
562 brd->u.board.conc1++;
564 DPR_INIT(("Adding CONC to config...\n"));
567 case CX: /* c/x type concentrator */
568 if (p->type != CNODE) {
569 dgap_err("cx only valid for concentrators");
573 p->u.conc.v_type = 1;
574 DPR_INIT(("Adding CX to config...\n"));
577 case EPC: /* epc type concentrator */
578 if (p->type != CNODE) {
579 dgap_err("cx only valid for concentrators");
582 p->u.conc.type = EPC;
583 p->u.conc.v_type = 1;
584 DPR_INIT(("Adding EPC to config...\n"));
587 case MOD: /* EBI module */
588 if (dgap_checknode(p))
591 dgap_err("must specify board info before EBI modules");
594 switch (brd->u.board.type) {
600 dgap_err("must specify concentrator info before EBI module");
604 if ( (p->next = dgap_newnode(MNODE)) == NULL ) {
605 dgap_err("out of memory");
610 brd->u.board.module2++;
612 brd->u.board.module1++;
614 DPR_INIT(("Adding MOD to config...\n"));
617 case PORTS: /* ports type EBI module */
618 if (p->type != MNODE) {
619 dgap_err("ports only valid for EBI modules");
622 p->u.module.type = PORTS;
623 p->u.module.v_type = 1;
624 DPR_INIT(("Adding PORTS to config...\n"));
627 case MODEM: /* ports type EBI module */
628 if (p->type != MNODE) {
629 dgap_err("modem only valid for modem modules");
632 p->u.module.type = MODEM;
633 p->u.module.v_type = 1;
634 DPR_INIT(("Adding MODEM to config...\n"));
638 if (p->type == LNODE) {
639 if ((s = dgap_getword(in)) == NULL) {
640 dgap_err("unexpected end of file");
643 p->u.line.cable = dgap_savestring(s);
644 p->u.line.v_cable = 1;
646 DPR_INIT(("Adding CABLE (%s) to config...\n", s));
649 case SPEED: /* sync line speed indication */
650 if (p->type == LNODE) {
651 s = dgap_getword(in);
653 dgap_err("unexpected end of file");
656 p->u.line.speed = (char)simple_strtol(s, &s2, 0);
657 if ((short)strlen(s) > (short)(s2 - s)) {
658 dgap_err("bad number for line speed");
661 p->u.line.v_speed = 1;
662 } else if (p->type == CNODE) {
663 s = dgap_getword(in);
665 dgap_err("unexpected end of file");
668 p->u.conc.speed = (char)simple_strtol(s, &s2, 0);
669 if ((short)strlen(s) > (short)(s2 - s)) {
670 dgap_err("bad number for line speed");
673 p->u.conc.v_speed = 1;
675 dgap_err("speed valid only for lines or concentrators.");
678 DPR_INIT(("Adding SPEED (%s) to config...\n", s));
682 if (p->type == CNODE) {
683 if ((s = dgap_getword(in)) == NULL) {
684 dgap_err("unexpected end of file");
687 p->u.conc.connect = dgap_savestring(s);
688 p->u.conc.v_connect = 1;
690 DPR_INIT(("Adding CONNECT (%s) to config...\n", s));
692 case PRINT: /* transparent print name prefix */
693 if (dgap_checknode(p))
695 if ( (p->next = dgap_newnode(PNODE)) == NULL ) {
696 dgap_err("out of memory");
700 if ( (s = dgap_getword(in)) == NULL ) {
701 dgap_err("unexpeced end of file");
704 if ( (p->u.printname = dgap_savestring(s)) == NULL ) {
705 dgap_err("out of memory");
708 DPR_INIT(("Adding PRINT (%s) to config...\n", s));
711 case CMAJOR: /* major number */
712 if (dgap_checknode(p))
714 if ( (p->next = dgap_newnode(JNODE)) == NULL ) {
715 dgap_err("out of memory");
719 s = dgap_getword(in);
721 dgap_err("unexpected end of file");
724 p->u.majornumber = simple_strtol(s, &s2, 0);
725 if ((int)strlen(s) > (int)(s2 - s)) {
726 dgap_err("bad number for major number");
729 DPR_INIT(("Adding CMAJOR (%s) to config...\n", s));
732 case ALTPIN: /* altpin setting */
733 if (dgap_checknode(p))
735 if ( (p->next = dgap_newnode(ANODE)) == NULL ) {
736 dgap_err("out of memory");
740 s = dgap_getword(in);
742 dgap_err("unexpected end of file");
745 p->u.altpin = simple_strtol(s, &s2, 0);
746 if ((int)strlen(s) > (int)(s2 - s)) {
747 dgap_err("bad number for altpin");
750 DPR_INIT(("Adding ALTPIN (%s) to config...\n", s));
753 case USEINTR: /* enable interrupt setting */
754 if (dgap_checknode(p))
756 if ( (p->next = dgap_newnode(INTRNODE)) == NULL ) {
757 dgap_err("out of memory");
761 s = dgap_getword(in);
763 dgap_err("unexpected end of file");
766 p->u.useintr = simple_strtol(s, &s2, 0);
767 if ((int)strlen(s) > (int)(s2 - s)) {
768 dgap_err("bad number for useintr");
771 DPR_INIT(("Adding USEINTR (%s) to config...\n", s));
774 case TTSIZ: /* size of tty structure */
775 if (dgap_checknode(p))
777 if ( (p->next = dgap_newnode(TSNODE)) == NULL ) {
778 dgap_err("out of memory");
782 s = dgap_getword(in);
784 dgap_err("unexpected end of file");
787 p->u.ttysize = simple_strtol(s, &s2, 0);
788 if ((int)strlen(s) > (int)(s2 - s)) {
789 dgap_err("bad number for ttysize");
792 DPR_INIT(("Adding TTSIZ (%s) to config...\n", s));
795 case CHSIZ: /* channel structure size */
796 if (dgap_checknode(p))
798 if ( (p->next = dgap_newnode(CSNODE)) == NULL ) {
799 dgap_err("out of memory");
803 s = dgap_getword(in);
805 dgap_err("unexpected end of file");
808 p->u.chsize = simple_strtol(s, &s2, 0);
809 if ((int)strlen(s) > (int)(s2 - s)) {
810 dgap_err("bad number for chsize");
813 DPR_INIT(("Adding CHSIZE (%s) to config...\n", s));
816 case BSSIZ: /* board structure size */
817 if (dgap_checknode(p))
819 if ( (p->next = dgap_newnode(BSNODE)) == NULL ) {
820 dgap_err("out of memory");
824 s = dgap_getword(in);
826 dgap_err("unexpected end of file");
829 p->u.bssize = simple_strtol(s, &s2, 0);
830 if ((int)strlen(s) > (int)(s2 - s)) {
831 dgap_err("bad number for bssize");
834 DPR_INIT(("Adding BSSIZ (%s) to config...\n", s));
837 case UNTSIZ: /* sched structure size */
838 if (dgap_checknode(p))
840 if ( (p->next = dgap_newnode(USNODE)) == NULL ) {
841 dgap_err("out of memory");
845 s = dgap_getword(in);
847 dgap_err("unexpected end of file");
850 p->u.unsize = simple_strtol(s, &s2, 0);
851 if ((int)strlen(s) > (int)(s2 - s)) {
852 dgap_err("bad number for schedsize");
855 DPR_INIT(("Adding UNTSIZ (%s) to config...\n", s));
858 case F2SIZ: /* f2200 structure size */
859 if (dgap_checknode(p))
861 if ( (p->next = dgap_newnode(FSNODE)) == NULL ) {
862 dgap_err("out of memory");
866 s = dgap_getword(in);
868 dgap_err("unexpected end of file");
871 p->u.f2size = simple_strtol(s, &s2, 0);
872 if ((int)strlen(s) > (int)(s2 - s)) {
873 dgap_err("bad number for f2200size");
876 DPR_INIT(("Adding F2SIZ (%s) to config...\n", s));
879 case VPSIZ: /* vpix structure size */
880 if (dgap_checknode(p))
882 if ( (p->next = dgap_newnode(VSNODE)) == NULL ) {
883 dgap_err("out of memory");
887 s = dgap_getword(in);
889 dgap_err("unexpected end of file");
892 p->u.vpixsize = simple_strtol(s, &s2, 0);
893 if ((int)strlen(s) > (int)(s2 - s)) {
894 dgap_err("bad number for vpixsize");
897 DPR_INIT(("Adding VPSIZ (%s) to config...\n", s));
905 * dgap_sindex: much like index(), but it looks for a match of any character in
906 * the group, and returns that position. If the first character is a ^, then
907 * this will match the first occurrence not in that group.
909 static char *dgap_sindex (char *string, char *group)
913 if (!string || !group)
914 return (char *) NULL;
918 for (; *string; string++) {
919 for (ptr = group; *ptr; ptr++) {
928 for (; *string; string++) {
929 for (ptr = group; *ptr; ptr++) {
936 return (char *) NULL;
941 * Get a token from the input file; return 0 if end of file is reached
943 static int dgap_gettok(char **in, struct cnode *p)
948 if (strstr(dgap_cword, "boar")) {
949 w = dgap_getword(in);
950 snprintf(dgap_cword, MAXCWORD, "%s", w);
951 for (t = dgap_tlist; t->token != 0; t++) {
952 if ( !strcmp(w, t->string)) {
956 dgap_err("board !!type not specified");
960 while ( (w = dgap_getword(in)) != NULL ) {
961 snprintf(dgap_cword, MAXCWORD, "%s", w);
962 for (t = dgap_tlist; t->token != 0; t++) {
963 if ( !strcmp(w, t->string) )
973 * get a word from the input stream, also keep track of current line number.
974 * words are separated by whitespace.
976 static char *dgap_getword(char **in)
980 char *ptr = dgap_sindex(*in, " \t\n");
982 /* If no word found, return null */
986 /* Mark new location for our buffer */
990 /* Eat any extra spaces/tabs/newlines that might be present */
991 while (*in && **in && ((**in == ' ') || (**in == '\t') || (**in == '\n'))) {
1001 * print an error message, giving the line number in the file where
1002 * the error occurred.
1004 static void dgap_err(char *s)
1006 printk("DGAP: parse: %s\n", s);
1011 * allocate a new configuration node of type t
1013 static struct cnode *dgap_newnode(int t)
1017 n = kmalloc(sizeof(struct cnode), GFP_ATOMIC);
1019 memset((char *)n, 0, sizeof(struct cnode));
1027 * dgap_checknode: see if all the necessary info has been supplied for a node
1028 * before creating the next node.
1030 static int dgap_checknode(struct cnode *p)
1034 if (p->u.board.v_type == 0) {
1035 dgap_err("board type !not specified");
1042 if (p->u.line.v_speed == 0) {
1043 dgap_err("line speed not specified");
1049 if (p->u.conc.v_type == 0) {
1050 dgap_err("concentrator type not specified");
1053 if (p->u.conc.v_speed == 0) {
1054 dgap_err("concentrator line speed not specified");
1057 if (p->u.conc.v_nport == 0) {
1058 dgap_err("number of ports on concentrator not specified");
1061 if (p->u.conc.v_id == 0) {
1062 dgap_err("concentrator id letter not specified");
1068 if (p->u.module.v_type == 0) {
1069 dgap_err("EBI module type not specified");
1072 if (p->u.module.v_nport == 0) {
1073 dgap_err("number of ports on EBI module not specified");
1076 if (p->u.module.v_id == 0) {
1077 dgap_err("EBI module id letter not specified");
1086 * save a string somewhere
1088 static char *dgap_savestring(char *s)
1091 if ( (p = kmalloc(strlen(s) + 1, GFP_ATOMIC) ) != NULL) {
1099 * Given a board pointer, returns whether we should use interrupts or not.
1101 uint dgap_config_get_useintr(struct board_t *bd)
1103 struct cnode *p = NULL;
1108 for (p = bd->bd_config; p; p = p->next) {
1112 * check for pcxr types.
1114 return p->u.useintr;
1120 /* If not found, then don't turn on interrupts. */
1126 * Given a board pointer, returns whether we turn on altpin or not.
1128 uint dgap_config_get_altpin(struct board_t *bd)
1130 struct cnode *p = NULL;
1135 for (p = bd->bd_config; p; p = p->next) {
1139 * check for pcxr types.
1147 /* If not found, then don't turn on interrupts. */
1154 * Given a specific type of board, if found, detached link and
1155 * returns the first occurrence in the list.
1157 struct cnode *dgap_find_config(int type, int bus, int slot)
1159 struct cnode *p, *prev = NULL, *prev2 = NULL, *found = NULL;
1163 while (p->next != NULL) {
1167 if (p->type == BNODE) {
1169 if (p->u.board.type == type) {
1171 if (p->u.board.v_pcibus && p->u.board.pcibus != bus) {
1172 DPR(("Found matching board, but wrong bus position. System says bus %d, we want bus %ld\n",
1173 bus, p->u.board.pcibus));
1176 if (p->u.board.v_pcislot && p->u.board.pcislot != slot) {
1177 DPR_INIT(("Found matching board, but wrong slot position. System says slot %d, we want slot %ld\n",
1178 slot, p->u.board.pcislot));
1182 DPR_INIT(("Matched type in config file\n"));
1186 * Keep walking thru the list till we find the next board.
1188 while (p->next != NULL) {
1191 if (p->type == BNODE) {
1194 * Mark the end of our 1 board chain of configs.
1199 * Link the "next" board to the previous board,
1200 * effectively "unlinking" our board from the main config.
1208 * It must be the last board in the list.
1219 * Given a board pointer, walks the config link, counting up
1220 * all ports user specified should be on the board.
1221 * (This does NOT mean they are all actually present right now tho)
1223 uint dgap_config_get_number_of_ports(struct board_t *bd)
1226 struct cnode *p = NULL;
1231 for (p = bd->bd_config; p; p = p->next) {
1236 * check for pcxr types.
1238 if (p->u.board.type > EPCFE)
1239 count += p->u.board.nport;
1242 count += p->u.conc.nport;
1245 count += p->u.module.nport;
1252 char *dgap_create_config_string(struct board_t *bd, char *string)
1255 struct cnode *p = NULL;
1256 struct cnode *q = NULL;
1264 for (p = bd->bd_config; p; p = p->next) {
1270 *ptr = p->u.line.speed;
1275 * Because the EPC/con concentrators can have EM modules
1276 * hanging off of them, we have to walk ahead in the list
1277 * and keep adding the number of ports on each EM to the config.
1280 speed = p->u.conc.speed;
1282 if ((q != NULL) && (q->type == MNODE) ) {
1283 *ptr = (p->u.conc.nport + 0x80);
1286 while ((q->next != NULL) && (q->next->type) == MNODE) {
1287 *ptr = (q->u.module.nport + 0x80);
1292 *ptr = q->u.module.nport;
1295 *ptr = p->u.conc.nport;
1311 char *dgap_get_config_letters(struct board_t *bd, char *string)
1315 struct cnode *cptr = NULL;
1317 int left = MAXTTYNAMELEN;
1323 for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
1325 if ((cptr->type == BNODE) &&
1326 ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
1327 (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
1328 (cptr->u.board.type == PAPORT8))) {
1333 if (cptr->type == TNODE && found == TRUE) {
1335 if (strstr(cptr->u.ttyname, "tty")) {
1336 ptr1 = cptr->u.ttyname;
1340 ptr1 = cptr->u.ttyname;
1343 len = snprintf(ptr, left, "%s", ptr1);
1351 if (cptr->type == CNODE) {
1352 if (cptr->u.conc.id) {
1353 len = snprintf(ptr, left, "%s", cptr->u.conc.id);
1361 if (cptr->type == MNODE) {
1362 if (cptr->u.module.id) {
1363 len = snprintf(ptr, left, "%s", cptr->u.module.id);