staging: dgap: Merge dgap_parses.c into dgap_driver.c
authorMark Hounschell <markh@compro.net>
Wed, 19 Feb 2014 18:12:02 +0000 (13:12 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 25 Feb 2014 00:48:11 +0000 (16:48 -0800)
There is a lot of cleanup work to do on these digi drivers and merging as
much as is possible will make it easier. I also notice that many merged
drivers are single source and header.

Signed-off-by: Mark Hounschell <markh@compro.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/dgap/Makefile
drivers/staging/dgap/dgap_driver.c
drivers/staging/dgap/dgap_parse.c [deleted file]

index f5c9e357f5007f0cec6f21d7164b140f3120f0e5..13bf6fb3737903bb8e5c3934acbe2a36e8557ef4 100644 (file)
@@ -2,5 +2,5 @@ obj-$(CONFIG_DGAP) += dgap.o
 
 
 dgap-objs :=   dgap_driver.o \
-               dgap_parse.o    dgap_trace.o 
+               dgap_trace.o 
 
index 93b72d376ce8d92a1d18e5e340305980efe7b1cf..cca35a0bf9e5625cc0f92b6af295f6529e08eea8 100644 (file)
@@ -136,6 +136,16 @@ static void dgap_tty_send_xchar(struct tty_struct *tty, char ch);
 static void dgap_cmdw_ext(struct channel_t *ch, u16 cmd, u16 word, uint ncmds);
 static int dgap_event(struct board_t *bd);
 
+/*
+ * Function prototypes from dgap_parse.c.
+ */
+static int dgap_gettok(char **in, struct cnode *p);
+static char *dgap_getword(char **in);
+static char *dgap_savestring(char *s);
+static struct cnode *dgap_newnode(int t);
+static int dgap_checknode(struct cnode *p);
+static void dgap_err(char *s);
+
 /* Driver load/unload functions */
 int                    dgap_init_module(void);
 void                   dgap_cleanup_module(void);
@@ -336,6 +346,68 @@ static const struct tty_operations dgap_tty_ops = {
        .send_xchar = dgap_tty_send_xchar
 };
 
+/*
+ * Our needed internal static variables from dgap_parse.c
+ */
+static struct cnode dgap_head;
+#define MAXCWORD 200
+static char dgap_cword[MAXCWORD];
+
+struct toklist {
+       int     token;
+       char    *string;
+};
+
+static struct toklist dgap_tlist[] = {
+       {       BEGIN,          "config_begin"                  },
+       {       END,            "config_end"                    },
+       {       BOARD,          "board"                         },
+       {       PCX,            "Digi_AccelePort_C/X_PCI"       },      /* C/X_PCI */
+       {       PEPC,           "Digi_AccelePort_EPC/X_PCI"     },      /* EPC/X_PCI */
+       {       PPCM,           "Digi_AccelePort_Xem_PCI"       },      /* PCI/Xem */
+       {       APORT2_920P,    "Digi_AccelePort_2r_920_PCI"    },
+       {       APORT4_920P,    "Digi_AccelePort_4r_920_PCI"    },
+       {       APORT8_920P,    "Digi_AccelePort_8r_920_PCI"    },
+       {       PAPORT4,        "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
+       {       PAPORT8,        "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
+       {       IO,             "io"                            },
+       {       PCIINFO,        "pciinfo"                       },
+       {       LINE,           "line"                          },
+       {       CONC,           "conc"                          },
+       {       CONC,           "concentrator"                  },
+       {       CX,             "cx"                            },
+       {       CX,             "ccon"                          },
+       {       EPC,            "epccon"                        },
+       {       EPC,            "epc"                           },
+       {       MOD,            "module"                        },
+       {       ID,             "id"                            },
+       {       STARTO,         "start"                         },
+       {       SPEED,          "speed"                         },
+       {       CABLE,          "cable"                         },
+       {       CONNECT,        "connect"                       },
+       {       METHOD,         "method"                        },
+       {       STATUS,         "status"                        },
+       {       CUSTOM,         "Custom"                        },
+       {       BASIC,          "Basic"                         },
+       {       MEM,            "mem"                           },
+       {       MEM,            "memory"                        },
+       {       PORTS,          "ports"                         },
+       {       MODEM,          "modem"                         },
+       {       NPORTS,         "nports"                        },
+       {       TTYN,           "ttyname"                       },
+       {       CU,             "cuname"                        },
+       {       PRINT,          "prname"                        },
+       {       CMAJOR,         "major"                         },
+       {       ALTPIN,         "altpin"                        },
+       {       USEINTR,        "useintr"                       },
+       {       TTSIZ,          "ttysize"                       },
+       {       CHSIZ,          "chsize"                        },
+       {       BSSIZ,          "boardsize"                     },
+       {       UNTSIZ,         "schedsize"                     },
+       {       F2SIZ,          "f2200size"                     },
+       {       VPSIZ,          "vpixsize"                      },
+       {       0,              NULL                            }
+};
 
 /************************************************************************
  *
@@ -7128,3 +7200,1256 @@ void dgap_remove_tty_sysfs(struct device *c)
 {
        sysfs_remove_group(&c->kobj, &dgap_tty_attribute_group);
 }
+
+/*
+ * Parse a configuration file read into memory as a string.
+ */
+int    dgap_parsefile(char **in, int Remove)
+{
+       struct cnode *p, *brd, *line, *conc;
+       int     rc;
+       char    *s = NULL, *s2 = NULL;
+       int     linecnt = 0;
+
+       p = &dgap_head;
+       brd = line = conc = NULL;
+
+       /* perhaps we are adding to an existing list? */
+       while (p->next != NULL) {
+               p = p->next;
+       }
+
+       /* file must start with a BEGIN */
+       while ( (rc = dgap_gettok(in,p)) != BEGIN ) {
+               if (rc == 0) {
+                       dgap_err("unexpected EOF");
+                       return(-1);
+               }
+       }
+
+       for (; ; ) {
+               rc = dgap_gettok(in,p);
+               if (rc == 0) {
+                       dgap_err("unexpected EOF");
+                       return(-1);
+               }
+
+               switch (rc) {
+               case 0:
+                       dgap_err("unexpected end of file");
+                       return(-1);
+
+               case BEGIN:     /* should only be 1 begin */
+                       dgap_err("unexpected config_begin\n");
+                       return(-1);
+
+               case END:
+                       return(0);
+
+               case BOARD:     /* board info */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(BNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+
+                       p->u.board.status = dgap_savestring("No");
+                       line = conc = NULL;
+                       brd = p;
+                       linecnt = -1;
+                       break;
+
+               case APORT2_920P:       /* AccelePort_4 */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected Digi_2r_920 string");
+                               return(-1);
+                       }
+                       p->u.board.type = APORT2_920P;
+                       p->u.board.v_type = 1;
+                       DPR_INIT(("Adding Digi_2r_920 PCI to config...\n"));
+                       break;
+
+               case APORT4_920P:       /* AccelePort_4 */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected Digi_4r_920 string");
+                               return(-1);
+                       }
+                       p->u.board.type = APORT4_920P;
+                       p->u.board.v_type = 1;
+                       DPR_INIT(("Adding Digi_4r_920 PCI to config...\n"));
+                       break;
+
+               case APORT8_920P:       /* AccelePort_8 */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected Digi_8r_920 string");
+                               return(-1);
+                       }
+                       p->u.board.type = APORT8_920P;
+                       p->u.board.v_type = 1;
+                       DPR_INIT(("Adding Digi_8r_920 PCI to config...\n"));
+                       break;
+
+               case PAPORT4:   /* AccelePort_4 PCI */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected Digi_4r(PCI) string");
+                               return(-1);
+                       }
+                       p->u.board.type = PAPORT4;
+                       p->u.board.v_type = 1;
+                       DPR_INIT(("Adding Digi_4r PCI to config...\n"));
+                       break;
+
+               case PAPORT8:   /* AccelePort_8 PCI */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected Digi_8r string");
+                               return(-1);
+                       }
+                       p->u.board.type = PAPORT8;
+                       p->u.board.v_type = 1;
+                       DPR_INIT(("Adding Digi_8r PCI to config...\n"));
+                       break;
+
+               case PCX:       /* PCI C/X */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected Digi_C/X_(PCI) string");
+                               return(-1);
+                       }
+                       p->u.board.type = PCX;
+                       p->u.board.v_type = 1;
+                       p->u.board.conc1 = 0;
+                       p->u.board.conc2 = 0;
+                       p->u.board.module1 = 0;
+                       p->u.board.module2 = 0;
+                       DPR_INIT(("Adding PCI C/X to config...\n"));
+                       break;
+
+               case PEPC:      /* PCI EPC/X */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected \"Digi_EPC/X_(PCI)\" string");
+                               return(-1);
+                       }
+                       p->u.board.type = PEPC;
+                       p->u.board.v_type = 1;
+                       p->u.board.conc1 = 0;
+                       p->u.board.conc2 = 0;
+                       p->u.board.module1 = 0;
+                       p->u.board.module2 = 0;
+                       DPR_INIT(("Adding PCI EPC/X to config...\n"));
+                       break;
+
+               case PPCM:      /* PCI/Xem */
+                       if (p->type != BNODE) {
+                               dgap_err("unexpected PCI/Xem string");
+                               return(-1);
+                       }
+                       p->u.board.type = PPCM;
+                       p->u.board.v_type = 1;
+                       p->u.board.conc1 = 0;
+                       p->u.board.conc2 = 0;
+                       DPR_INIT(("Adding PCI XEM to config...\n"));
+                       break;
+
+               case IO:        /* i/o port */
+                       if (p->type != BNODE) {
+                               dgap_err("IO port only vaild for boards");
+                               return(-1);
+                       }
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.board.portstr = dgap_savestring(s);
+                       p->u.board.port = (short)simple_strtol(s, &s2, 0);
+                       if ((short)strlen(s) > (short)(s2 - s)) {
+                               dgap_err("bad number for IO port");
+                               return(-1);
+                       }
+                       p->u.board.v_port = 1;
+                       DPR_INIT(("Adding IO (%s) to config...\n", s));
+                       break;
+
+               case MEM:       /* memory address */
+                       if (p->type != BNODE) {
+                               dgap_err("memory address only vaild for boards");
+                               return(-1);
+                       }
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.board.addrstr = dgap_savestring(s);
+                       p->u.board.addr = simple_strtoul(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for memory address");
+                               return(-1);
+                       }
+                       p->u.board.v_addr = 1;
+                       DPR_INIT(("Adding MEM (%s) to config...\n", s));
+                       break;
+
+               case PCIINFO:   /* pci information */
+                       if (p->type != BNODE) {
+                               dgap_err("memory address only vaild for boards");
+                               return(-1);
+                       }
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.board.pcibusstr = dgap_savestring(s);
+                       p->u.board.pcibus = simple_strtoul(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for pci bus");
+                               return(-1);
+                       }
+                       p->u.board.v_pcibus = 1;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.board.pcislotstr = dgap_savestring(s);
+                       p->u.board.pcislot = simple_strtoul(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for pci slot");
+                               return(-1);
+                       }
+                       p->u.board.v_pcislot = 1;
+
+                       DPR_INIT(("Adding PCIINFO (%s %s) to config...\n", p->u.board.pcibusstr,
+                               p->u.board.pcislotstr));
+                       break;
+
+               case METHOD:
+                       if (p->type != BNODE) {
+                               dgap_err("install method only vaild for boards");
+                               return(-1);
+                       }
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.board.method = dgap_savestring(s);
+                       p->u.board.v_method = 1;
+                       DPR_INIT(("Adding METHOD (%s) to config...\n", s));
+                       break;
+
+               case STATUS:
+                       if (p->type != BNODE) {
+                               dgap_err("config status only vaild for boards");
+                               return(-1);
+                       }
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.board.status = dgap_savestring(s);
+                       DPR_INIT(("Adding STATUS (%s) to config...\n", s));
+                       break;
+
+               case NPORTS:    /* number of ports */
+                       if (p->type == BNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.board.nport = (char)simple_strtol(s, &s2, 0);
+                               if ((int)strlen(s) > (int)(s2 - s)) {
+                                       dgap_err("bad number for number of ports");
+                                       return(-1);
+                               }
+                               p->u.board.v_nport = 1;
+                       } else if (p->type == CNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.conc.nport = (char)simple_strtol(s, &s2, 0);
+                               if ((int)strlen(s) > (int)(s2 - s)) {
+                                       dgap_err("bad number for number of ports");
+                                       return(-1);
+                               }
+                               p->u.conc.v_nport = 1;
+                       } else if (p->type == MNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.module.nport = (char)simple_strtol(s, &s2, 0);
+                               if ((int)strlen(s) > (int)(s2 - s)) {
+                                       dgap_err("bad number for number of ports");
+                                       return(-1);
+                               }
+                               p->u.module.v_nport = 1;
+                       } else {
+                               dgap_err("nports only valid for concentrators or modules");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding NPORTS (%s) to config...\n", s));
+                       break;
+
+               case ID:        /* letter ID used in tty name */
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+
+                       p->u.board.status = dgap_savestring(s);
+
+                       if (p->type == CNODE) {
+                               p->u.conc.id = dgap_savestring(s);
+                               p->u.conc.v_id = 1;
+                       } else if (p->type == MNODE) {
+                               p->u.module.id = dgap_savestring(s);
+                               p->u.module.v_id = 1;
+                       } else {
+                               dgap_err("id only valid for concentrators or modules");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding ID (%s) to config...\n", s));
+                       break;
+
+               case STARTO:    /* start offset of ID */
+                       if (p->type == BNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.board.start = simple_strtol(s, &s2, 0);
+                               if ((int)strlen(s) > (int)(s2 - s)) {
+                                       dgap_err("bad number for start of tty count");
+                                       return(-1);
+                               }
+                               p->u.board.v_start = 1;
+                       } else if (p->type == CNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.conc.start = simple_strtol(s, &s2, 0);
+                               if ((int)strlen(s) > (int)(s2 - s)) {
+                                       dgap_err("bad number for start of tty count");
+                                       return(-1);
+                               }
+                               p->u.conc.v_start = 1;
+                       } else if (p->type == MNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.module.start = simple_strtol(s, &s2, 0);
+                               if ((int)strlen(s) > (int)(s2 - s)) {
+                                       dgap_err("bad number for start of tty count");
+                                       return(-1);
+                               }
+                               p->u.module.v_start = 1;
+                       } else {
+                               dgap_err("start only valid for concentrators or modules");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding START (%s) to config...\n", s));
+                       break;
+
+               case TTYN:      /* tty name prefix */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(TNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       if ( (s = dgap_getword(in)) == NULL ) {
+                               dgap_err("unexpeced end of file");
+                               return(-1);
+                       }
+                       if ( (p->u.ttyname = dgap_savestring(s)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding TTY (%s) to config...\n", s));
+                       break;
+
+               case CU:        /* cu name prefix */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(CUNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       if ( (s = dgap_getword(in)) == NULL ) {
+                               dgap_err("unexpeced end of file");
+                               return(-1);
+                       }
+                       if ( (p->u.cuname = dgap_savestring(s)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding CU (%s) to config...\n", s));
+                       break;
+
+               case LINE:      /* line information */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if (brd == NULL) {
+                               dgap_err("must specify board before line info");
+                               return(-1);
+                       }
+                       switch (brd->u.board.type) {
+                       case PPCM:
+                               dgap_err("line not vaild for PC/em");
+                               return(-1);
+                       }
+                       if ( (p->next = dgap_newnode(LNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       conc = NULL;
+                       line = p;
+                       linecnt++;
+                       DPR_INIT(("Adding LINE to config...\n"));
+                       break;
+
+               case CONC:      /* concentrator information */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if (line == NULL) {
+                               dgap_err("must specify line info before concentrator");
+                               return(-1);
+                       }
+                       if ( (p->next = dgap_newnode(CNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       conc = p;
+                       if (linecnt)
+                               brd->u.board.conc2++;
+                       else
+                               brd->u.board.conc1++;
+
+                       DPR_INIT(("Adding CONC to config...\n"));
+                       break;
+
+               case CX:        /* c/x type concentrator */
+                       if (p->type != CNODE) {
+                               dgap_err("cx only valid for concentrators");
+                               return(-1);
+                       }
+                       p->u.conc.type = CX;
+                       p->u.conc.v_type = 1;
+                       DPR_INIT(("Adding CX to config...\n"));
+                       break;
+
+               case EPC:       /* epc type concentrator */
+                       if (p->type != CNODE) {
+                               dgap_err("cx only valid for concentrators");
+                               return(-1);
+                       }
+                       p->u.conc.type = EPC;
+                       p->u.conc.v_type = 1;
+                       DPR_INIT(("Adding EPC to config...\n"));
+                       break;
+
+               case MOD:       /* EBI module */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if (brd == NULL) {
+                               dgap_err("must specify board info before EBI modules");
+                               return(-1);
+                       }
+                       switch (brd->u.board.type) {
+                       case PPCM:
+                               linecnt = 0;
+                               break;
+                       default:
+                               if (conc == NULL) {
+                                       dgap_err("must specify concentrator info before EBI module");
+                                       return(-1);
+                               }
+                       }
+                       if ( (p->next = dgap_newnode(MNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       if (linecnt)
+                               brd->u.board.module2++;
+                       else
+                               brd->u.board.module1++;
+
+                       DPR_INIT(("Adding MOD to config...\n"));
+                       break;
+
+               case PORTS:     /* ports type EBI module */
+                       if (p->type != MNODE) {
+                               dgap_err("ports only valid for EBI modules");
+                               return(-1);
+                       }
+                       p->u.module.type = PORTS;
+                       p->u.module.v_type = 1;
+                       DPR_INIT(("Adding PORTS to config...\n"));
+                       break;
+
+               case MODEM:     /* ports type EBI module */
+                       if (p->type != MNODE) {
+                               dgap_err("modem only valid for modem modules");
+                               return(-1);
+                       }
+                       p->u.module.type = MODEM;
+                       p->u.module.v_type = 1;
+                       DPR_INIT(("Adding MODEM to config...\n"));
+                       break;
+
+               case CABLE:
+                       if (p->type == LNODE) {
+                               if ((s = dgap_getword(in)) == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.line.cable = dgap_savestring(s);
+                               p->u.line.v_cable = 1;
+                       }
+                       DPR_INIT(("Adding CABLE (%s) to config...\n", s));
+                       break;
+
+               case SPEED:     /* sync line speed indication */
+                       if (p->type == LNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.line.speed = (char)simple_strtol(s, &s2, 0);
+                               if ((short)strlen(s) > (short)(s2 - s)) {
+                                       dgap_err("bad number for line speed");
+                                       return(-1);
+                               }
+                               p->u.line.v_speed = 1;
+                       } else if (p->type == CNODE) {
+                               s = dgap_getword(in);
+                               if (s == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.conc.speed = (char)simple_strtol(s, &s2, 0);
+                               if ((short)strlen(s) > (short)(s2 - s)) {
+                                       dgap_err("bad number for line speed");
+                                       return(-1);
+                               }
+                               p->u.conc.v_speed = 1;
+                       } else {
+                               dgap_err("speed valid only for lines or concentrators.");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding SPEED (%s) to config...\n", s));
+                       break;
+
+               case CONNECT:
+                       if (p->type == CNODE) {
+                               if ((s = dgap_getword(in)) == NULL) {
+                                       dgap_err("unexpected end of file");
+                                       return(-1);
+                               }
+                               p->u.conc.connect = dgap_savestring(s);
+                               p->u.conc.v_connect = 1;
+                       }
+                       DPR_INIT(("Adding CONNECT (%s) to config...\n", s));
+                       break;
+               case PRINT:     /* transparent print name prefix */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(PNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       if ( (s = dgap_getword(in)) == NULL ) {
+                               dgap_err("unexpeced end of file");
+                               return(-1);
+                       }
+                       if ( (p->u.printname = dgap_savestring(s)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding PRINT (%s) to config...\n", s));
+                       break;
+
+               case CMAJOR:    /* major number */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(JNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.majornumber = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for major number");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding CMAJOR (%s) to config...\n", s));
+                       break;
+
+               case ALTPIN:    /* altpin setting */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(ANODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.altpin = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for altpin");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding ALTPIN (%s) to config...\n", s));
+                       break;
+
+               case USEINTR:           /* enable interrupt setting */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(INTRNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.useintr = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for useintr");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding USEINTR (%s) to config...\n", s));
+                       break;
+
+               case TTSIZ:     /* size of tty structure */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(TSNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.ttysize = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for ttysize");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding TTSIZ (%s) to config...\n", s));
+                       break;
+
+               case CHSIZ:     /* channel structure size */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(CSNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.chsize = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for chsize");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding CHSIZE (%s) to config...\n", s));
+                       break;
+
+               case BSSIZ:     /* board structure size */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(BSNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.bssize = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for bssize");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding BSSIZ (%s) to config...\n", s));
+                       break;
+
+               case UNTSIZ:    /* sched structure size */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(USNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.unsize = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for schedsize");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding UNTSIZ (%s) to config...\n", s));
+                       break;
+
+               case F2SIZ:     /* f2200 structure size */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(FSNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.f2size = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for f2200size");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding F2SIZ (%s) to config...\n", s));
+                       break;
+
+               case VPSIZ:     /* vpix structure size */
+                       if (dgap_checknode(p))
+                               return(-1);
+                       if ( (p->next = dgap_newnode(VSNODE)) == NULL ) {
+                               dgap_err("out of memory");
+                               return(-1);
+                       }
+                       p = p->next;
+                       s = dgap_getword(in);
+                       if (s == NULL) {
+                               dgap_err("unexpected end of file");
+                               return(-1);
+                       }
+                       p->u.vpixsize = simple_strtol(s, &s2, 0);
+                       if ((int)strlen(s) > (int)(s2 - s)) {
+                               dgap_err("bad number for vpixsize");
+                               return(-1);
+                       }
+                       DPR_INIT(("Adding VPSIZ (%s) to config...\n", s));
+                       break;
+               }
+       }
+}
+
+
+/*
+ * dgap_sindex: much like index(), but it looks for a match of any character in
+ * the group, and returns that position.  If the first character is a ^, then
+ * this will match the first occurrence not in that group.
+ */
+static char *dgap_sindex (char *string, char *group)
+{
+       char    *ptr;
+
+       if (!string || !group)
+               return (char *) NULL;
+
+       if (*group == '^') {
+               group++;
+               for (; *string; string++) {
+                       for (ptr = group; *ptr; ptr++) {
+                               if (*ptr == *string)
+                                       break;
+                       }
+                       if (*ptr == '\0')
+                               return string;
+               }
+       }
+       else {
+               for (; *string; string++) {
+                       for (ptr = group; *ptr; ptr++) {
+                               if (*ptr == *string)
+                                       return string;
+                       }
+               }
+       }
+
+       return (char *) NULL;
+}
+
+
+/*
+ * Get a token from the input file; return 0 if end of file is reached
+ */
+static int dgap_gettok(char **in, struct cnode *p)
+{
+       char    *w;
+       struct toklist *t;
+
+       if (strstr(dgap_cword, "boar")) {
+               w = dgap_getword(in);
+               snprintf(dgap_cword, MAXCWORD, "%s", w);
+               for (t = dgap_tlist; t->token != 0; t++) {
+                       if ( !strcmp(w, t->string)) {
+                               return(t->token);
+                       }
+               }
+               dgap_err("board !!type not specified");
+               return(1);
+       }
+       else {
+               while ( (w = dgap_getword(in)) != NULL ) {
+                       snprintf(dgap_cword, MAXCWORD, "%s", w);
+                       for (t = dgap_tlist; t->token != 0; t++) {
+                               if ( !strcmp(w, t->string) )
+                                       return(t->token);
+                       }
+               }
+               return(0);
+       }
+}
+
+
+/*
+ * get a word from the input stream, also keep track of current line number.
+ * words are separated by whitespace.
+ */
+static char *dgap_getword(char **in)
+{
+       char *ret_ptr = *in;
+
+        char *ptr = dgap_sindex(*in, " \t\n");
+
+       /* If no word found, return null */
+       if (!ptr)
+               return NULL;
+
+       /* Mark new location for our buffer */
+       *ptr = '\0';
+       *in = ptr + 1;
+
+       /* Eat any extra spaces/tabs/newlines that might be present */
+       while (*in && **in && ((**in == ' ') || (**in == '\t') || (**in == '\n'))) {
+               **in = '\0';
+               *in = *in + 1;
+       }
+
+       return ret_ptr;
+}
+
+
+/*
+ * print an error message, giving the line number in the file where
+ * the error occurred.
+ */
+static void dgap_err(char *s)
+{
+       printk("DGAP: parse: %s\n", s);
+}
+
+
+/*
+ * allocate a new configuration node of type t
+ */
+static struct cnode *dgap_newnode(int t)
+{
+       struct cnode *n;
+
+       n = kmalloc(sizeof(struct cnode), GFP_ATOMIC);
+       if (n != NULL) {
+               memset((char *)n, 0, sizeof(struct cnode));
+               n->type = t;
+       }
+       return(n);
+}
+
+
+/*
+ * dgap_checknode: see if all the necessary info has been supplied for a node
+ * before creating the next node.
+ */
+static int dgap_checknode(struct cnode *p)
+{
+       switch (p->type) {
+       case BNODE:
+               if (p->u.board.v_type == 0) {
+                       dgap_err("board type !not specified");
+                       return(1);
+               }
+
+               return(0);
+
+       case LNODE:
+               if (p->u.line.v_speed == 0) {
+                       dgap_err("line speed not specified");
+                       return(1);
+               }
+               return(0);
+
+       case CNODE:
+               if (p->u.conc.v_type == 0) {
+                       dgap_err("concentrator type not specified");
+                       return(1);
+               }
+               if (p->u.conc.v_speed == 0) {
+                       dgap_err("concentrator line speed not specified");
+                       return(1);
+               }
+               if (p->u.conc.v_nport == 0) {
+                       dgap_err("number of ports on concentrator not specified");
+                       return(1);
+               }
+               if (p->u.conc.v_id == 0) {
+                       dgap_err("concentrator id letter not specified");
+                       return(1);
+               }
+               return(0);
+
+       case MNODE:
+               if (p->u.module.v_type == 0) {
+                       dgap_err("EBI module type not specified");
+                       return(1);
+               }
+               if (p->u.module.v_nport == 0) {
+                       dgap_err("number of ports on EBI module not specified");
+                       return(1);
+               }
+               if (p->u.module.v_id == 0) {
+                       dgap_err("EBI module id letter not specified");
+                       return(1);
+               }
+               return(0);
+       }
+       return(0);
+}
+
+/*
+ * save a string somewhere
+ */
+static char    *dgap_savestring(char *s)
+{
+       char    *p;
+       if ( (p = kmalloc(strlen(s) + 1, GFP_ATOMIC) ) != NULL) {
+               strcpy(p, s);
+       }
+       return(p);
+}
+
+
+/*
+ * Given a board pointer, returns whether we should use interrupts or not.
+ */
+uint dgap_config_get_useintr(struct board_t *bd)
+{
+       struct cnode *p = NULL;
+
+       if (!bd)
+               return(0);
+
+       for (p = bd->bd_config; p; p = p->next) {
+               switch (p->type) {
+               case INTRNODE:
+                       /*
+                        * check for pcxr types.
+                        */
+                       return p->u.useintr;
+               default:
+                       break;
+               }
+       }
+
+       /* If not found, then don't turn on interrupts. */
+       return 0;
+}
+
+
+/*
+ * Given a board pointer, returns whether we turn on altpin or not.
+ */
+uint dgap_config_get_altpin(struct board_t *bd)
+{
+       struct cnode *p = NULL;
+
+       if (!bd)
+               return(0);
+
+       for (p = bd->bd_config; p; p = p->next) {
+               switch (p->type) {
+               case ANODE:
+                       /*
+                        * check for pcxr types.
+                        */
+                       return p->u.altpin;
+               default:
+                       break;
+               }
+       }
+
+       /* If not found, then don't turn on interrupts. */
+       return 0;
+}
+
+
+
+/*
+ * Given a specific type of board, if found, detached link and
+ * returns the first occurrence in the list.
+ */
+struct cnode *dgap_find_config(int type, int bus, int slot)
+{
+       struct cnode *p, *prev = NULL, *prev2 = NULL, *found = NULL;
+
+       p = &dgap_head;
+
+       while (p->next != NULL) {
+               prev = p;
+               p = p->next;
+
+               if (p->type == BNODE) {
+
+                       if (p->u.board.type == type) {
+
+                               if (p->u.board.v_pcibus && p->u.board.pcibus != bus) {
+                                       DPR(("Found matching board, but wrong bus position. System says bus %d, we want bus %ld\n",
+                                               bus, p->u.board.pcibus));
+                                       continue;
+                               }
+                               if (p->u.board.v_pcislot && p->u.board.pcislot != slot) {
+                                       DPR_INIT(("Found matching board, but wrong slot position. System says slot %d, we want slot %ld\n",
+                                               slot, p->u.board.pcislot));
+                                       continue;
+                               }
+
+                               DPR_INIT(("Matched type in config file\n"));
+
+                               found = p;
+                               /*
+                                * Keep walking thru the list till we find the next board.
+                                */
+                               while (p->next != NULL) {
+                                       prev2 = p;
+                                       p = p->next;
+                                       if (p->type == BNODE) {
+
+                                               /*
+                                                * Mark the end of our 1 board chain of configs.
+                                                */
+                                               prev2->next = NULL;
+
+                                               /*
+                                                * Link the "next" board to the previous board,
+                                                * effectively "unlinking" our board from the main config.
+                                                */
+                                               prev->next = p;
+
+                                               return found;
+                                       }
+                               }
+                               /*
+                                * It must be the last board in the list.
+                                */
+                               prev->next = NULL;
+                               return found;
+                       }
+               }
+       }
+       return NULL;
+}
+
+/*
+ * Given a board pointer, walks the config link, counting up
+ * all ports user specified should be on the board.
+ * (This does NOT mean they are all actually present right now tho)
+ */
+uint dgap_config_get_number_of_ports(struct board_t *bd)
+{
+       int count = 0;
+       struct cnode *p = NULL;
+
+       if (!bd)
+               return(0);
+
+       for (p = bd->bd_config; p; p = p->next) {
+
+               switch (p->type) {
+               case BNODE:
+                       /*
+                        * check for pcxr types.
+                        */
+                       if (p->u.board.type > EPCFE)
+                               count += p->u.board.nport;
+                       break;
+               case CNODE:
+                       count += p->u.conc.nport;
+                       break;
+               case MNODE:
+                       count += p->u.module.nport;
+                       break;
+               }
+       }
+       return (count);
+}
+
+char *dgap_create_config_string(struct board_t *bd, char *string)
+{
+       char *ptr = string;
+       struct cnode *p = NULL;
+       struct cnode *q = NULL;
+       int speed;
+
+       if (!bd) {
+               *ptr = 0xff;
+               return string;
+       }
+
+       for (p = bd->bd_config; p; p = p->next) {
+
+               switch (p->type) {
+               case LNODE:
+                       *ptr = '\0';
+                       ptr++;
+                       *ptr = p->u.line.speed;
+                       ptr++;
+                       break;
+               case CNODE:
+                       /*
+                        * Because the EPC/con concentrators can have EM modules
+                        * hanging off of them, we have to walk ahead in the list
+                        * and keep adding the number of ports on each EM to the config.
+                        * UGH!
+                        */
+                       speed = p->u.conc.speed;
+                       q = p->next;
+                       if ((q != NULL) && (q->type == MNODE) ) {
+                               *ptr = (p->u.conc.nport + 0x80);
+                               ptr++;
+                               p = q;
+                               while ((q->next != NULL) && (q->next->type) == MNODE) {
+                                       *ptr = (q->u.module.nport + 0x80);
+                                       ptr++;
+                                       p = q;
+                                       q = q->next;
+                               }
+                               *ptr = q->u.module.nport;
+                               ptr++;
+                       } else {
+                               *ptr = p->u.conc.nport;
+                               ptr++;
+                       }
+
+                       *ptr = speed;
+                       ptr++;
+                       break;
+               }
+       }
+
+       *ptr = 0xff;
+       return string;
+}
+
+
+
+char *dgap_get_config_letters(struct board_t *bd, char *string)
+{
+       int found = FALSE;
+       char *ptr = string;
+       struct cnode *cptr = NULL;
+       int len = 0;
+       int left = MAXTTYNAMELEN;
+
+       if (!bd) {
+               return "<NULL>";
+       }
+
+       for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
+
+               if ((cptr->type == BNODE) &&
+                    ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
+                    (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
+                    (cptr->u.board.type == PAPORT8))) {
+
+                       found = TRUE;
+               }
+
+               if (cptr->type == TNODE && found == TRUE) {
+                       char *ptr1;
+                       if (strstr(cptr->u.ttyname, "tty")) {
+                               ptr1 = cptr->u.ttyname;
+                               ptr1 += 3;
+                       }
+                       else {
+                               ptr1 = cptr->u.ttyname;
+                       }
+                       if (ptr1) {
+                               len = snprintf(ptr, left, "%s", ptr1);
+                               left -= len;
+                               ptr  += len;
+                               if (left <= 0)
+                                       break;
+                       }
+               }
+
+               if (cptr->type == CNODE) {
+                       if (cptr->u.conc.id) {
+                               len = snprintf(ptr, left, "%s", cptr->u.conc.id);
+                               left -= len;
+                               ptr  += len;
+                               if (left <= 0)
+                                       break;
+                       }
+                }
+
+               if (cptr->type == MNODE) {
+                       if (cptr->u.module.id) {
+                               len = snprintf(ptr, left, "%s", cptr->u.module.id);
+                               left -= len;
+                               ptr  += len;
+                               if (left <= 0)
+                                       break;
+                       }
+               }
+       }
+
+       return string;
+}
diff --git a/drivers/staging/dgap/dgap_parse.c b/drivers/staging/dgap/dgap_parse.c
deleted file mode 100644 (file)
index 65cd612..0000000
+++ /dev/null
@@ -1,1373 +0,0 @@
-/*
- * Copyright 2003 Digi International (www.digi.com)
- *     Scott H Kilau <Scott_Kilau at digi dot com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *
- *     NOTE TO LINUX KERNEL HACKERS:  DO NOT REFORMAT THIS CODE!
- *
- *     This is shared code between Digi's CVS archive and the
- *     Linux Kernel sources.
- *     Changing the source just for reformatting needlessly breaks
- *     our CVS diff history.
- *
- *     Send any bug fixes/changes to:  Eng.Linux at digi dot com.
- *     Thank you.
- *
- *
- *****************************************************************************
- *
- * dgap_parse.c - Parses the configuration information from the input file.
- *
- *
- */
-#include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/slab.h>
-
-#include "dgap_types.h"
-#include "dgap_fep5.h"
-#include "dgap_driver.h"
-#include "dgap_parse.h"
-#include "dgap_conf.h"
-
-
-/*
- * Function prototypes.
- */
-static int dgap_gettok(char **in, struct cnode *p);
-static char *dgap_getword(char **in);
-static char *dgap_savestring(char *s);
-static struct cnode *dgap_newnode(int t);
-static int dgap_checknode(struct cnode *p);
-static void dgap_err(char *s);
-
-/*
- * Our needed internal static variables...
- */
-static struct cnode dgap_head;
-#define MAXCWORD 200
-static char dgap_cword[MAXCWORD];
-
-struct toklist {
-       int     token;
-       char    *string;
-};
-
-static struct toklist dgap_tlist[] = {
-       {       BEGIN,          "config_begin"                  },
-       {       END,            "config_end"                    },
-       {       BOARD,          "board"                         },
-       {       PCX,            "Digi_AccelePort_C/X_PCI"       },      /* C/X_PCI */
-       {       PEPC,           "Digi_AccelePort_EPC/X_PCI"     },      /* EPC/X_PCI */
-       {       PPCM,           "Digi_AccelePort_Xem_PCI"       },      /* PCI/Xem */
-       {       APORT2_920P,    "Digi_AccelePort_2r_920_PCI"    },
-       {       APORT4_920P,    "Digi_AccelePort_4r_920_PCI"    },
-       {       APORT8_920P,    "Digi_AccelePort_8r_920_PCI"    },
-       {       PAPORT4,        "Digi_AccelePort_4r_PCI(EIA-232/RS-422)" },
-       {       PAPORT8,        "Digi_AccelePort_8r_PCI(EIA-232/RS-422)" },
-       {       IO,             "io"                            },
-       {       PCIINFO,        "pciinfo"                       },
-       {       LINE,           "line"                          },
-       {       CONC,           "conc"                          },
-       {       CONC,           "concentrator"                  },
-       {       CX,             "cx"                            },
-       {       CX,             "ccon"                          },
-       {       EPC,            "epccon"                        },
-       {       EPC,            "epc"                           },
-       {       MOD,            "module"                        },
-       {       ID,             "id"                            },
-       {       STARTO,         "start"                         },
-       {       SPEED,          "speed"                         },
-       {       CABLE,          "cable"                         },
-       {       CONNECT,        "connect"                       },
-       {       METHOD,         "method"                        },
-       {       STATUS,         "status"                        },
-       {       CUSTOM,         "Custom"                        },
-       {       BASIC,          "Basic"                         },
-       {       MEM,            "mem"                           },
-       {       MEM,            "memory"                        },
-       {       PORTS,          "ports"                         },
-       {       MODEM,          "modem"                         },
-       {       NPORTS,         "nports"                        },
-       {       TTYN,           "ttyname"                       },
-       {       CU,             "cuname"                        },
-       {       PRINT,          "prname"                        },
-       {       CMAJOR,         "major"                         },
-       {       ALTPIN,         "altpin"                        },
-       {       USEINTR,        "useintr"                       },
-       {       TTSIZ,          "ttysize"                       },
-       {       CHSIZ,          "chsize"                        },
-       {       BSSIZ,          "boardsize"                     },
-       {       UNTSIZ,         "schedsize"                     },
-       {       F2SIZ,          "f2200size"                     },
-       {       VPSIZ,          "vpixsize"                      },
-       {       0,              NULL                            }
-};
-
-
-/*
- * Parse a configuration file read into memory as a string.
- */
-int    dgap_parsefile(char **in, int Remove)
-{
-       struct cnode *p, *brd, *line, *conc;
-       int     rc;
-       char    *s = NULL, *s2 = NULL;
-       int     linecnt = 0;
-
-       p = &dgap_head;
-       brd = line = conc = NULL;
-
-       /* perhaps we are adding to an existing list? */
-       while (p->next != NULL) {
-               p = p->next;
-       }
-
-       /* file must start with a BEGIN */
-       while ( (rc = dgap_gettok(in,p)) != BEGIN ) {
-               if (rc == 0) {
-                       dgap_err("unexpected EOF");
-                       return(-1);
-               }
-       }
-
-       for (; ; ) {
-               rc = dgap_gettok(in,p);
-               if (rc == 0) {
-                       dgap_err("unexpected EOF");
-                       return(-1);
-               }
-
-               switch (rc) {
-               case 0:
-                       dgap_err("unexpected end of file");
-                       return(-1);
-
-               case BEGIN:     /* should only be 1 begin */
-                       dgap_err("unexpected config_begin\n");
-                       return(-1);
-
-               case END:
-                       return(0);
-
-               case BOARD:     /* board info */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(BNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-
-                       p->u.board.status = dgap_savestring("No");
-                       line = conc = NULL;
-                       brd = p;
-                       linecnt = -1;
-                       break;
-
-               case APORT2_920P:       /* AccelePort_4 */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected Digi_2r_920 string");
-                               return(-1);
-                       }
-                       p->u.board.type = APORT2_920P;
-                       p->u.board.v_type = 1;
-                       DPR_INIT(("Adding Digi_2r_920 PCI to config...\n"));
-                       break;
-
-               case APORT4_920P:       /* AccelePort_4 */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected Digi_4r_920 string");
-                               return(-1);
-                       }
-                       p->u.board.type = APORT4_920P;
-                       p->u.board.v_type = 1;
-                       DPR_INIT(("Adding Digi_4r_920 PCI to config...\n"));
-                       break;
-
-               case APORT8_920P:       /* AccelePort_8 */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected Digi_8r_920 string");
-                               return(-1);
-                       }
-                       p->u.board.type = APORT8_920P;
-                       p->u.board.v_type = 1;
-                       DPR_INIT(("Adding Digi_8r_920 PCI to config...\n"));
-                       break;
-
-               case PAPORT4:   /* AccelePort_4 PCI */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected Digi_4r(PCI) string");
-                               return(-1);
-                       }
-                       p->u.board.type = PAPORT4;
-                       p->u.board.v_type = 1;
-                       DPR_INIT(("Adding Digi_4r PCI to config...\n"));
-                       break;
-
-               case PAPORT8:   /* AccelePort_8 PCI */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected Digi_8r string");
-                               return(-1);
-                       }
-                       p->u.board.type = PAPORT8;
-                       p->u.board.v_type = 1;
-                       DPR_INIT(("Adding Digi_8r PCI to config...\n"));
-                       break;
-
-               case PCX:       /* PCI C/X */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected Digi_C/X_(PCI) string");
-                               return(-1);
-                       }
-                       p->u.board.type = PCX;
-                       p->u.board.v_type = 1;
-                       p->u.board.conc1 = 0;
-                       p->u.board.conc2 = 0;
-                       p->u.board.module1 = 0;
-                       p->u.board.module2 = 0;
-                       DPR_INIT(("Adding PCI C/X to config...\n"));
-                       break;
-
-               case PEPC:      /* PCI EPC/X */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected \"Digi_EPC/X_(PCI)\" string");
-                               return(-1);
-                       }
-                       p->u.board.type = PEPC;
-                       p->u.board.v_type = 1;
-                       p->u.board.conc1 = 0;
-                       p->u.board.conc2 = 0;
-                       p->u.board.module1 = 0;
-                       p->u.board.module2 = 0;
-                       DPR_INIT(("Adding PCI EPC/X to config...\n"));
-                       break;
-
-               case PPCM:      /* PCI/Xem */
-                       if (p->type != BNODE) {
-                               dgap_err("unexpected PCI/Xem string");
-                               return(-1);
-                       }
-                       p->u.board.type = PPCM;
-                       p->u.board.v_type = 1;
-                       p->u.board.conc1 = 0;
-                       p->u.board.conc2 = 0;
-                       DPR_INIT(("Adding PCI XEM to config...\n"));
-                       break;
-
-               case IO:        /* i/o port */
-                       if (p->type != BNODE) {
-                               dgap_err("IO port only vaild for boards");
-                               return(-1);
-                       }
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.board.portstr = dgap_savestring(s);
-                       p->u.board.port = (short)simple_strtol(s, &s2, 0);
-                       if ((short)strlen(s) > (short)(s2 - s)) {
-                               dgap_err("bad number for IO port");
-                               return(-1);
-                       }
-                       p->u.board.v_port = 1;
-                       DPR_INIT(("Adding IO (%s) to config...\n", s));
-                       break;
-
-               case MEM:       /* memory address */
-                       if (p->type != BNODE) {
-                               dgap_err("memory address only vaild for boards");
-                               return(-1);
-                       }
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.board.addrstr = dgap_savestring(s);
-                       p->u.board.addr = simple_strtoul(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for memory address");
-                               return(-1);
-                       }
-                       p->u.board.v_addr = 1;
-                       DPR_INIT(("Adding MEM (%s) to config...\n", s));
-                       break;
-
-               case PCIINFO:   /* pci information */
-                       if (p->type != BNODE) {
-                               dgap_err("memory address only vaild for boards");
-                               return(-1);
-                       }
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.board.pcibusstr = dgap_savestring(s);
-                       p->u.board.pcibus = simple_strtoul(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for pci bus");
-                               return(-1);
-                       }
-                       p->u.board.v_pcibus = 1;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.board.pcislotstr = dgap_savestring(s);
-                       p->u.board.pcislot = simple_strtoul(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for pci slot");
-                               return(-1);
-                       }
-                       p->u.board.v_pcislot = 1;
-
-                       DPR_INIT(("Adding PCIINFO (%s %s) to config...\n", p->u.board.pcibusstr,
-                               p->u.board.pcislotstr));
-                       break;
-
-               case METHOD:
-                       if (p->type != BNODE) {
-                               dgap_err("install method only vaild for boards");
-                               return(-1);
-                       }
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.board.method = dgap_savestring(s);
-                       p->u.board.v_method = 1;
-                       DPR_INIT(("Adding METHOD (%s) to config...\n", s));
-                       break;
-
-               case STATUS:
-                       if (p->type != BNODE) {
-                               dgap_err("config status only vaild for boards");
-                               return(-1);
-                       }
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.board.status = dgap_savestring(s);
-                       DPR_INIT(("Adding STATUS (%s) to config...\n", s));
-                       break;
-
-               case NPORTS:    /* number of ports */
-                       if (p->type == BNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.board.nport = (char)simple_strtol(s, &s2, 0);
-                               if ((int)strlen(s) > (int)(s2 - s)) {
-                                       dgap_err("bad number for number of ports");
-                                       return(-1);
-                               }
-                               p->u.board.v_nport = 1;
-                       } else if (p->type == CNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.conc.nport = (char)simple_strtol(s, &s2, 0);
-                               if ((int)strlen(s) > (int)(s2 - s)) {
-                                       dgap_err("bad number for number of ports");
-                                       return(-1);
-                               }
-                               p->u.conc.v_nport = 1;
-                       } else if (p->type == MNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.module.nport = (char)simple_strtol(s, &s2, 0);
-                               if ((int)strlen(s) > (int)(s2 - s)) {
-                                       dgap_err("bad number for number of ports");
-                                       return(-1);
-                               }
-                               p->u.module.v_nport = 1;
-                       } else {
-                               dgap_err("nports only valid for concentrators or modules");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding NPORTS (%s) to config...\n", s));
-                       break;
-
-               case ID:        /* letter ID used in tty name */
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-
-                       p->u.board.status = dgap_savestring(s);
-
-                       if (p->type == CNODE) {
-                               p->u.conc.id = dgap_savestring(s);
-                               p->u.conc.v_id = 1;
-                       } else if (p->type == MNODE) {
-                               p->u.module.id = dgap_savestring(s);
-                               p->u.module.v_id = 1;
-                       } else {
-                               dgap_err("id only valid for concentrators or modules");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding ID (%s) to config...\n", s));
-                       break;
-
-               case STARTO:    /* start offset of ID */
-                       if (p->type == BNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.board.start = simple_strtol(s, &s2, 0);
-                               if ((int)strlen(s) > (int)(s2 - s)) {
-                                       dgap_err("bad number for start of tty count");
-                                       return(-1);
-                               }
-                               p->u.board.v_start = 1;
-                       } else if (p->type == CNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.conc.start = simple_strtol(s, &s2, 0);
-                               if ((int)strlen(s) > (int)(s2 - s)) {
-                                       dgap_err("bad number for start of tty count");
-                                       return(-1);
-                               }
-                               p->u.conc.v_start = 1;
-                       } else if (p->type == MNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.module.start = simple_strtol(s, &s2, 0);
-                               if ((int)strlen(s) > (int)(s2 - s)) {
-                                       dgap_err("bad number for start of tty count");
-                                       return(-1);
-                               }
-                               p->u.module.v_start = 1;
-                       } else {
-                               dgap_err("start only valid for concentrators or modules");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding START (%s) to config...\n", s));
-                       break;
-
-               case TTYN:      /* tty name prefix */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(TNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       if ( (s = dgap_getword(in)) == NULL ) {
-                               dgap_err("unexpeced end of file");
-                               return(-1);
-                       }
-                       if ( (p->u.ttyname = dgap_savestring(s)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding TTY (%s) to config...\n", s));
-                       break;
-
-               case CU:        /* cu name prefix */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(CUNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       if ( (s = dgap_getword(in)) == NULL ) {
-                               dgap_err("unexpeced end of file");
-                               return(-1);
-                       }
-                       if ( (p->u.cuname = dgap_savestring(s)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding CU (%s) to config...\n", s));
-                       break;
-
-               case LINE:      /* line information */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if (brd == NULL) {
-                               dgap_err("must specify board before line info");
-                               return(-1);
-                       }
-                       switch (brd->u.board.type) {
-                       case PPCM:
-                               dgap_err("line not vaild for PC/em");
-                               return(-1);
-                       }
-                       if ( (p->next = dgap_newnode(LNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       conc = NULL;
-                       line = p;
-                       linecnt++;
-                       DPR_INIT(("Adding LINE to config...\n"));
-                       break;
-
-               case CONC:      /* concentrator information */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if (line == NULL) {
-                               dgap_err("must specify line info before concentrator");
-                               return(-1);
-                       }
-                       if ( (p->next = dgap_newnode(CNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       conc = p;
-                       if (linecnt)
-                               brd->u.board.conc2++;
-                       else
-                               brd->u.board.conc1++;
-
-                       DPR_INIT(("Adding CONC to config...\n"));
-                       break;
-
-               case CX:        /* c/x type concentrator */
-                       if (p->type != CNODE) {
-                               dgap_err("cx only valid for concentrators");
-                               return(-1);
-                       }
-                       p->u.conc.type = CX;
-                       p->u.conc.v_type = 1;
-                       DPR_INIT(("Adding CX to config...\n"));
-                       break;
-
-               case EPC:       /* epc type concentrator */
-                       if (p->type != CNODE) {
-                               dgap_err("cx only valid for concentrators");
-                               return(-1);
-                       }
-                       p->u.conc.type = EPC;
-                       p->u.conc.v_type = 1;
-                       DPR_INIT(("Adding EPC to config...\n"));
-                       break;
-
-               case MOD:       /* EBI module */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if (brd == NULL) {
-                               dgap_err("must specify board info before EBI modules");
-                               return(-1);
-                       }
-                       switch (brd->u.board.type) {
-                       case PPCM:
-                               linecnt = 0;
-                               break;
-                       default:
-                               if (conc == NULL) {
-                                       dgap_err("must specify concentrator info before EBI module");
-                                       return(-1);
-                               }
-                       }
-                       if ( (p->next = dgap_newnode(MNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       if (linecnt)
-                               brd->u.board.module2++;
-                       else
-                               brd->u.board.module1++;
-
-                       DPR_INIT(("Adding MOD to config...\n"));
-                       break;
-
-               case PORTS:     /* ports type EBI module */
-                       if (p->type != MNODE) {
-                               dgap_err("ports only valid for EBI modules");
-                               return(-1);
-                       }
-                       p->u.module.type = PORTS;
-                       p->u.module.v_type = 1;
-                       DPR_INIT(("Adding PORTS to config...\n"));
-                       break;
-
-               case MODEM:     /* ports type EBI module */
-                       if (p->type != MNODE) {
-                               dgap_err("modem only valid for modem modules");
-                               return(-1);
-                       }
-                       p->u.module.type = MODEM;
-                       p->u.module.v_type = 1;
-                       DPR_INIT(("Adding MODEM to config...\n"));
-                       break;
-
-               case CABLE:
-                       if (p->type == LNODE) {
-                               if ((s = dgap_getword(in)) == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.line.cable = dgap_savestring(s);
-                               p->u.line.v_cable = 1;
-                       }
-                       DPR_INIT(("Adding CABLE (%s) to config...\n", s));
-                       break;
-
-               case SPEED:     /* sync line speed indication */
-                       if (p->type == LNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.line.speed = (char)simple_strtol(s, &s2, 0);
-                               if ((short)strlen(s) > (short)(s2 - s)) {
-                                       dgap_err("bad number for line speed");
-                                       return(-1);
-                               }
-                               p->u.line.v_speed = 1;
-                       } else if (p->type == CNODE) {
-                               s = dgap_getword(in);
-                               if (s == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.conc.speed = (char)simple_strtol(s, &s2, 0);
-                               if ((short)strlen(s) > (short)(s2 - s)) {
-                                       dgap_err("bad number for line speed");
-                                       return(-1);
-                               }
-                               p->u.conc.v_speed = 1;
-                       } else {
-                               dgap_err("speed valid only for lines or concentrators.");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding SPEED (%s) to config...\n", s));
-                       break;
-
-               case CONNECT:
-                       if (p->type == CNODE) {
-                               if ((s = dgap_getword(in)) == NULL) {
-                                       dgap_err("unexpected end of file");
-                                       return(-1);
-                               }
-                               p->u.conc.connect = dgap_savestring(s);
-                               p->u.conc.v_connect = 1;
-                       }
-                       DPR_INIT(("Adding CONNECT (%s) to config...\n", s));
-                       break;
-               case PRINT:     /* transparent print name prefix */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(PNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       if ( (s = dgap_getword(in)) == NULL ) {
-                               dgap_err("unexpeced end of file");
-                               return(-1);
-                       }
-                       if ( (p->u.printname = dgap_savestring(s)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding PRINT (%s) to config...\n", s));
-                       break;
-
-               case CMAJOR:    /* major number */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(JNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.majornumber = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for major number");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding CMAJOR (%s) to config...\n", s));
-                       break;
-
-               case ALTPIN:    /* altpin setting */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(ANODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.altpin = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for altpin");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding ALTPIN (%s) to config...\n", s));
-                       break;
-
-               case USEINTR:           /* enable interrupt setting */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(INTRNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.useintr = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for useintr");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding USEINTR (%s) to config...\n", s));
-                       break;
-
-               case TTSIZ:     /* size of tty structure */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(TSNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.ttysize = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for ttysize");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding TTSIZ (%s) to config...\n", s));
-                       break;
-
-               case CHSIZ:     /* channel structure size */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(CSNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.chsize = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for chsize");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding CHSIZE (%s) to config...\n", s));
-                       break;
-
-               case BSSIZ:     /* board structure size */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(BSNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.bssize = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for bssize");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding BSSIZ (%s) to config...\n", s));
-                       break;
-
-               case UNTSIZ:    /* sched structure size */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(USNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.unsize = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for schedsize");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding UNTSIZ (%s) to config...\n", s));
-                       break;
-
-               case F2SIZ:     /* f2200 structure size */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(FSNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.f2size = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for f2200size");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding F2SIZ (%s) to config...\n", s));
-                       break;
-
-               case VPSIZ:     /* vpix structure size */
-                       if (dgap_checknode(p))
-                               return(-1);
-                       if ( (p->next = dgap_newnode(VSNODE)) == NULL ) {
-                               dgap_err("out of memory");
-                               return(-1);
-                       }
-                       p = p->next;
-                       s = dgap_getword(in);
-                       if (s == NULL) {
-                               dgap_err("unexpected end of file");
-                               return(-1);
-                       }
-                       p->u.vpixsize = simple_strtol(s, &s2, 0);
-                       if ((int)strlen(s) > (int)(s2 - s)) {
-                               dgap_err("bad number for vpixsize");
-                               return(-1);
-                       }
-                       DPR_INIT(("Adding VPSIZ (%s) to config...\n", s));
-                       break;
-               }
-       }
-}
-
-
-/*
- * dgap_sindex: much like index(), but it looks for a match of any character in
- * the group, and returns that position.  If the first character is a ^, then
- * this will match the first occurrence not in that group.
- */
-static char *dgap_sindex (char *string, char *group)
-{
-       char    *ptr;
-
-       if (!string || !group)
-               return (char *) NULL;
-
-       if (*group == '^') {
-               group++;
-               for (; *string; string++) {
-                       for (ptr = group; *ptr; ptr++) {
-                               if (*ptr == *string)
-                                       break;
-                       }
-                       if (*ptr == '\0')
-                               return string;
-               }
-       }
-       else {
-               for (; *string; string++) {
-                       for (ptr = group; *ptr; ptr++) {
-                               if (*ptr == *string)
-                                       return string;
-                       }
-               }
-       }
-
-       return (char *) NULL;
-}
-
-
-/*
- * Get a token from the input file; return 0 if end of file is reached
- */
-static int dgap_gettok(char **in, struct cnode *p)
-{
-       char    *w;
-       struct toklist *t;
-
-       if (strstr(dgap_cword, "boar")) {
-               w = dgap_getword(in);
-               snprintf(dgap_cword, MAXCWORD, "%s", w);
-               for (t = dgap_tlist; t->token != 0; t++) {
-                       if ( !strcmp(w, t->string)) {
-                               return(t->token);
-                       }
-               }
-               dgap_err("board !!type not specified");
-               return(1);
-       }
-       else {
-               while ( (w = dgap_getword(in)) != NULL ) {
-                       snprintf(dgap_cword, MAXCWORD, "%s", w);
-                       for (t = dgap_tlist; t->token != 0; t++) {
-                               if ( !strcmp(w, t->string) )
-                                       return(t->token);
-                       }
-               }
-               return(0);
-       }
-}
-
-
-/*
- * get a word from the input stream, also keep track of current line number.
- * words are separated by whitespace.
- */
-static char *dgap_getword(char **in)
-{
-       char *ret_ptr = *in;
-
-        char *ptr = dgap_sindex(*in, " \t\n");
-
-       /* If no word found, return null */
-       if (!ptr)
-               return NULL;
-
-       /* Mark new location for our buffer */
-       *ptr = '\0';
-       *in = ptr + 1;
-
-       /* Eat any extra spaces/tabs/newlines that might be present */
-       while (*in && **in && ((**in == ' ') || (**in == '\t') || (**in == '\n'))) {
-               **in = '\0';
-               *in = *in + 1;
-       }
-
-       return ret_ptr;
-}
-
-
-/*
- * print an error message, giving the line number in the file where
- * the error occurred.
- */
-static void dgap_err(char *s)
-{
-       printk("DGAP: parse: %s\n", s);
-}
-
-
-/*
- * allocate a new configuration node of type t
- */
-static struct cnode *dgap_newnode(int t)
-{
-       struct cnode *n;
-
-       n = kmalloc(sizeof(struct cnode), GFP_ATOMIC);
-       if (n != NULL) {
-               memset((char *)n, 0, sizeof(struct cnode));
-               n->type = t;
-       }
-       return(n);
-}
-
-
-/*
- * dgap_checknode: see if all the necessary info has been supplied for a node
- * before creating the next node.
- */
-static int dgap_checknode(struct cnode *p)
-{
-       switch (p->type) {
-       case BNODE:
-               if (p->u.board.v_type == 0) {
-                       dgap_err("board type !not specified");
-                       return(1);
-               }
-
-               return(0);
-
-       case LNODE:
-               if (p->u.line.v_speed == 0) {
-                       dgap_err("line speed not specified");
-                       return(1);
-               }
-               return(0);
-
-       case CNODE:
-               if (p->u.conc.v_type == 0) {
-                       dgap_err("concentrator type not specified");
-                       return(1);
-               }
-               if (p->u.conc.v_speed == 0) {
-                       dgap_err("concentrator line speed not specified");
-                       return(1);
-               }
-               if (p->u.conc.v_nport == 0) {
-                       dgap_err("number of ports on concentrator not specified");
-                       return(1);
-               }
-               if (p->u.conc.v_id == 0) {
-                       dgap_err("concentrator id letter not specified");
-                       return(1);
-               }
-               return(0);
-
-       case MNODE:
-               if (p->u.module.v_type == 0) {
-                       dgap_err("EBI module type not specified");
-                       return(1);
-               }
-               if (p->u.module.v_nport == 0) {
-                       dgap_err("number of ports on EBI module not specified");
-                       return(1);
-               }
-               if (p->u.module.v_id == 0) {
-                       dgap_err("EBI module id letter not specified");
-                       return(1);
-               }
-               return(0);
-       }
-       return(0);
-}
-
-/*
- * save a string somewhere
- */
-static char    *dgap_savestring(char *s)
-{
-       char    *p;
-       if ( (p = kmalloc(strlen(s) + 1, GFP_ATOMIC) ) != NULL) {
-               strcpy(p, s);
-       }
-       return(p);
-}
-
-
-/*
- * Given a board pointer, returns whether we should use interrupts or not.
- */
-uint dgap_config_get_useintr(struct board_t *bd)
-{
-       struct cnode *p = NULL;
-
-       if (!bd)
-               return(0);
-
-       for (p = bd->bd_config; p; p = p->next) {
-               switch (p->type) {
-               case INTRNODE:
-                       /*
-                        * check for pcxr types.
-                        */
-                       return p->u.useintr;
-               default:
-                       break;
-               }
-       }
-
-       /* If not found, then don't turn on interrupts. */
-       return 0;
-}
-
-
-/*
- * Given a board pointer, returns whether we turn on altpin or not.
- */
-uint dgap_config_get_altpin(struct board_t *bd)
-{
-       struct cnode *p = NULL;
-
-       if (!bd)
-               return(0);
-
-       for (p = bd->bd_config; p; p = p->next) {
-               switch (p->type) {
-               case ANODE:
-                       /*
-                        * check for pcxr types.
-                        */
-                       return p->u.altpin;
-               default:
-                       break;
-               }
-       }
-
-       /* If not found, then don't turn on interrupts. */
-       return 0;
-}
-
-
-
-/*
- * Given a specific type of board, if found, detached link and
- * returns the first occurrence in the list.
- */
-struct cnode *dgap_find_config(int type, int bus, int slot)
-{
-       struct cnode *p, *prev = NULL, *prev2 = NULL, *found = NULL;
-
-       p = &dgap_head;
-
-       while (p->next != NULL) {
-               prev = p;
-               p = p->next;
-
-               if (p->type == BNODE) {
-
-                       if (p->u.board.type == type) {
-
-                               if (p->u.board.v_pcibus && p->u.board.pcibus != bus) {
-                                       DPR(("Found matching board, but wrong bus position. System says bus %d, we want bus %ld\n",
-                                               bus, p->u.board.pcibus));
-                                       continue;
-                               }
-                               if (p->u.board.v_pcislot && p->u.board.pcislot != slot) {
-                                       DPR_INIT(("Found matching board, but wrong slot position. System says slot %d, we want slot %ld\n",
-                                               slot, p->u.board.pcislot));
-                                       continue;
-                               }
-
-                               DPR_INIT(("Matched type in config file\n"));
-
-                               found = p;
-                               /*
-                                * Keep walking thru the list till we find the next board.
-                                */
-                               while (p->next != NULL) {
-                                       prev2 = p;
-                                       p = p->next;
-                                       if (p->type == BNODE) {
-
-                                               /*
-                                                * Mark the end of our 1 board chain of configs.
-                                                */
-                                               prev2->next = NULL;
-
-                                               /*
-                                                * Link the "next" board to the previous board,
-                                                * effectively "unlinking" our board from the main config.
-                                                */
-                                               prev->next = p;
-
-                                               return found;
-                                       }
-                               }
-                               /*
-                                * It must be the last board in the list.
-                                */
-                               prev->next = NULL;
-                               return found;
-                       }
-               }
-       }
-       return NULL;
-}
-
-/*
- * Given a board pointer, walks the config link, counting up
- * all ports user specified should be on the board.
- * (This does NOT mean they are all actually present right now tho)
- */
-uint dgap_config_get_number_of_ports(struct board_t *bd)
-{
-       int count = 0;
-       struct cnode *p = NULL;
-
-       if (!bd)
-               return(0);
-
-       for (p = bd->bd_config; p; p = p->next) {
-
-               switch (p->type) {
-               case BNODE:
-                       /*
-                        * check for pcxr types.
-                        */
-                       if (p->u.board.type > EPCFE)
-                               count += p->u.board.nport;
-                       break;
-               case CNODE:
-                       count += p->u.conc.nport;
-                       break;
-               case MNODE:
-                       count += p->u.module.nport;
-                       break;
-               }
-       }
-       return (count);
-}
-
-char *dgap_create_config_string(struct board_t *bd, char *string)
-{
-       char *ptr = string;
-       struct cnode *p = NULL;
-       struct cnode *q = NULL;
-       int speed;
-
-       if (!bd) {
-               *ptr = 0xff;
-               return string;
-       }
-
-       for (p = bd->bd_config; p; p = p->next) {
-
-               switch (p->type) {
-               case LNODE:
-                       *ptr = '\0';
-                       ptr++;
-                       *ptr = p->u.line.speed;
-                       ptr++;
-                       break;
-               case CNODE:
-                       /*
-                        * Because the EPC/con concentrators can have EM modules
-                        * hanging off of them, we have to walk ahead in the list
-                        * and keep adding the number of ports on each EM to the config.
-                        * UGH!
-                        */
-                       speed = p->u.conc.speed;
-                       q = p->next;
-                       if ((q != NULL) && (q->type == MNODE) ) {
-                               *ptr = (p->u.conc.nport + 0x80);
-                               ptr++;
-                               p = q;
-                               while ((q->next != NULL) && (q->next->type) == MNODE) {
-                                       *ptr = (q->u.module.nport + 0x80);
-                                       ptr++;
-                                       p = q;
-                                       q = q->next;
-                               }
-                               *ptr = q->u.module.nport;
-                               ptr++;
-                       } else {
-                               *ptr = p->u.conc.nport;
-                               ptr++;
-                       }
-
-                       *ptr = speed;
-                       ptr++;
-                       break;
-               }
-       }
-
-       *ptr = 0xff;
-       return string;
-}
-
-
-
-char *dgap_get_config_letters(struct board_t *bd, char *string)
-{
-       int found = FALSE;
-       char *ptr = string;
-       struct cnode *cptr = NULL;
-       int len = 0;
-       int left = MAXTTYNAMELEN;
-
-       if (!bd) {
-               return "<NULL>";
-       }
-
-       for (cptr = bd->bd_config; cptr; cptr = cptr->next) {
-
-               if ((cptr->type == BNODE) &&
-                    ((cptr->u.board.type == APORT2_920P) || (cptr->u.board.type == APORT4_920P) ||
-                    (cptr->u.board.type == APORT8_920P) || (cptr->u.board.type == PAPORT4) ||
-                    (cptr->u.board.type == PAPORT8))) {
-
-                       found = TRUE;
-               }
-
-               if (cptr->type == TNODE && found == TRUE) {
-                       char *ptr1;
-                       if (strstr(cptr->u.ttyname, "tty")) {
-                               ptr1 = cptr->u.ttyname;
-                               ptr1 += 3;
-                       }
-                       else {
-                               ptr1 = cptr->u.ttyname;
-                       }
-                       if (ptr1) {
-                               len = snprintf(ptr, left, "%s", ptr1);
-                               left -= len;
-                               ptr  += len;
-                               if (left <= 0)
-                                       break;
-                       }
-               }
-
-               if (cptr->type == CNODE) {
-                       if (cptr->u.conc.id) {
-                               len = snprintf(ptr, left, "%s", cptr->u.conc.id);
-                               left -= len;
-                               ptr  += len;
-                               if (left <= 0)
-                                       break;
-                       }
-                }
-
-               if (cptr->type == MNODE) {
-                       if (cptr->u.module.id) {
-                               len = snprintf(ptr, left, "%s", cptr->u.module.id);
-                               left -= len;
-                               ptr  += len;
-                               if (left <= 0)
-                                       break;
-                       }
-               }
-       }
-
-       return string;
-}