diff --git a/drivers/staging/dgap/Makefile b/drivers/staging/dgap/Makefile index f5c9e357f500..13bf6fb37379 100644 --- a/drivers/staging/dgap/Makefile +++ b/drivers/staging/dgap/Makefile @@ -2,5 +2,5 @@ obj-$(CONFIG_DGAP) += dgap.o dgap-objs := dgap_driver.o \ - dgap_parse.o dgap_trace.o + dgap_trace.o diff --git a/drivers/staging/dgap/dgap_driver.c b/drivers/staging/dgap/dgap_driver.c index 93b72d376ce8..cca35a0bf9e5 100644 --- a/drivers/staging/dgap/dgap_driver.c +++ b/drivers/staging/dgap/dgap_driver.c @@ -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 ""; + } + + 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 index 65cd6127951b..000000000000 --- a/drivers/staging/dgap/dgap_parse.c +++ /dev/null @@ -1,1373 +0,0 @@ -/* - * Copyright 2003 Digi International (www.digi.com) - * Scott H Kilau - * - * 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 -#include -#include - -#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 ""; - } - - 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; -}