in drivers/staging/dgap/dgap.c [6342:7015]
static int dgap_parsefile(char **in)
{
struct cnode *p, *brd, *line, *conc;
int rc;
char *s;
int linecnt = 0;
p = &dgap_head;
brd = line = conc = NULL;
/* perhaps we are adding to an existing list? */
while (p->next)
p = p->next;
/* file must start with a BEGIN */
while ((rc = dgap_gettok(in)) != BEGIN) {
if (rc == 0) {
pr_err("unexpected EOF");
return -1;
}
}
for (; ;) {
int board_type = 0;
int conc_type = 0;
int module_type = 0;
rc = dgap_gettok(in);
if (rc == 0) {
pr_err("unexpected EOF");
return -1;
}
switch (rc) {
case BEGIN: /* should only be 1 begin */
pr_err("unexpected config_begin\n");
return -1;
case END:
return 0;
case BOARD: /* board info */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = BNODE;
p->u.board.status = kstrdup("No", GFP_KERNEL);
line = conc = NULL;
brd = p;
linecnt = -1;
board_type = dgap_gettok(in);
if (board_type == 0) {
pr_err("board !!type not specified");
return -1;
}
p->u.board.type = board_type;
break;
case IO: /* i/o port */
if (p->type != BNODE) {
pr_err("IO port only vaild for boards");
return -1;
}
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.board.portstr = kstrdup(s, GFP_KERNEL);
if (kstrtol(s, 0, &p->u.board.port)) {
pr_err("bad number for IO port");
return -1;
}
p->u.board.v_port = 1;
break;
case MEM: /* memory address */
if (p->type != BNODE) {
pr_err("memory address only vaild for boards");
return -1;
}
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.board.addrstr = kstrdup(s, GFP_KERNEL);
if (kstrtoul(s, 0, &p->u.board.addr)) {
pr_err("bad number for memory address");
return -1;
}
p->u.board.v_addr = 1;
break;
case PCIINFO: /* pci information */
if (p->type != BNODE) {
pr_err("memory address only vaild for boards");
return -1;
}
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.board.pcibusstr = kstrdup(s, GFP_KERNEL);
if (kstrtoul(s, 0, &p->u.board.pcibus)) {
pr_err("bad number for pci bus");
return -1;
}
p->u.board.v_pcibus = 1;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.board.pcislotstr = kstrdup(s, GFP_KERNEL);
if (kstrtoul(s, 0, &p->u.board.pcislot)) {
pr_err("bad number for pci slot");
return -1;
}
p->u.board.v_pcislot = 1;
break;
case METHOD:
if (p->type != BNODE) {
pr_err("install method only vaild for boards");
return -1;
}
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.board.method = kstrdup(s, GFP_KERNEL);
p->u.board.v_method = 1;
break;
case STATUS:
if (p->type != BNODE) {
pr_err("config status only vaild for boards");
return -1;
}
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.board.status = kstrdup(s, GFP_KERNEL);
break;
case NPORTS: /* number of ports */
if (p->type == BNODE) {
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.board.nport)) {
pr_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) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.conc.nport)) {
pr_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) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.module.nport)) {
pr_err("bad number for number of ports");
return -1;
}
p->u.module.v_nport = 1;
} else {
pr_err("nports only valid for concentrators or modules");
return -1;
}
break;
case ID: /* letter ID used in tty name */
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.board.status = kstrdup(s, GFP_KERNEL);
if (p->type == CNODE) {
p->u.conc.id = kstrdup(s, GFP_KERNEL);
p->u.conc.v_id = 1;
} else if (p->type == MNODE) {
p->u.module.id = kstrdup(s, GFP_KERNEL);
p->u.module.v_id = 1;
} else {
pr_err("id only valid for concentrators or modules");
return -1;
}
break;
case STARTO: /* start offset of ID */
if (p->type == BNODE) {
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.board.start)) {
pr_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) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.conc.start)) {
pr_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) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.module.start)) {
pr_err("bad number for start of tty count");
return -1;
}
p->u.module.v_start = 1;
} else {
pr_err("start only valid for concentrators or modules");
return -1;
}
break;
case TTYN: /* tty name prefix */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = TNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpeced end of file");
return -1;
}
p->u.ttyname = kstrdup(s, GFP_KERNEL);
if (!p->u.ttyname)
return -1;
break;
case CU: /* cu name prefix */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = CUNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpeced end of file");
return -1;
}
p->u.cuname = kstrdup(s, GFP_KERNEL);
if (!p->u.cuname)
return -1;
break;
case LINE: /* line information */
if (dgap_checknode(p))
return -1;
if (!brd) {
pr_err("must specify board before line info");
return -1;
}
switch (brd->u.board.type) {
case PPCM:
pr_err("line not vaild for PC/em");
return -1;
}
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = LNODE;
conc = NULL;
line = p;
linecnt++;
break;
case CONC: /* concentrator information */
if (dgap_checknode(p))
return -1;
if (!line) {
pr_err("must specify line info before concentrator");
return -1;
}
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = CNODE;
conc = p;
if (linecnt)
brd->u.board.conc2++;
else
brd->u.board.conc1++;
conc_type = dgap_gettok(in);
if (conc_type == 0 || conc_type != CX ||
conc_type != EPC) {
pr_err("failed to set a type of concentratros");
return -1;
}
p->u.conc.type = conc_type;
break;
case MOD: /* EBI module */
if (dgap_checknode(p))
return -1;
if (!brd) {
pr_err("must specify board info before EBI modules");
return -1;
}
switch (brd->u.board.type) {
case PPCM:
linecnt = 0;
break;
default:
if (!conc) {
pr_err("must specify concentrator info before EBI module");
return -1;
}
}
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = MNODE;
if (linecnt)
brd->u.board.module2++;
else
brd->u.board.module1++;
module_type = dgap_gettok(in);
if (module_type == 0 || module_type != PORTS ||
module_type != MODEM) {
pr_err("failed to set a type of module");
return -1;
}
p->u.module.type = module_type;
break;
case CABLE:
if (p->type == LNODE) {
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.line.cable = kstrdup(s, GFP_KERNEL);
p->u.line.v_cable = 1;
}
break;
case SPEED: /* sync line speed indication */
if (p->type == LNODE) {
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.line.speed)) {
pr_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) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.conc.speed)) {
pr_err("bad number for line speed");
return -1;
}
p->u.conc.v_speed = 1;
} else {
pr_err("speed valid only for lines or concentrators.");
return -1;
}
break;
case CONNECT:
if (p->type == CNODE) {
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
p->u.conc.connect = kstrdup(s, GFP_KERNEL);
p->u.conc.v_connect = 1;
}
break;
case PRINT: /* transparent print name prefix */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = PNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpeced end of file");
return -1;
}
p->u.printname = kstrdup(s, GFP_KERNEL);
if (!p->u.printname)
return -1;
break;
case CMAJOR: /* major number */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = JNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.majornumber)) {
pr_err("bad number for major number");
return -1;
}
break;
case ALTPIN: /* altpin setting */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = ANODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.altpin)) {
pr_err("bad number for altpin");
return -1;
}
break;
case USEINTR: /* enable interrupt setting */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = INTRNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.useintr)) {
pr_err("bad number for useintr");
return -1;
}
break;
case TTSIZ: /* size of tty structure */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = TSNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.ttysize)) {
pr_err("bad number for ttysize");
return -1;
}
break;
case CHSIZ: /* channel structure size */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = CSNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.chsize)) {
pr_err("bad number for chsize");
return -1;
}
break;
case BSSIZ: /* board structure size */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = BSNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.bssize)) {
pr_err("bad number for bssize");
return -1;
}
break;
case UNTSIZ: /* sched structure size */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = USNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.unsize)) {
pr_err("bad number for schedsize");
return -1;
}
break;
case F2SIZ: /* f2200 structure size */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = FSNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.f2size)) {
pr_err("bad number for f2200size");
return -1;
}
break;
case VPSIZ: /* vpix structure size */
if (dgap_checknode(p))
return -1;
p->next = kzalloc(sizeof(struct cnode), GFP_KERNEL);
if (!p->next)
return -1;
p = p->next;
p->type = VSNODE;
s = dgap_getword(in);
if (!s) {
pr_err("unexpected end of file");
return -1;
}
if (kstrtol(s, 0, &p->u.vpixsize)) {
pr_err("bad number for vpixsize");
return -1;
}
break;
}
}
}