linux/drivers/net/skfp/smtparse.c

468 lines
9.8 KiB
C

/******************************************************************************
*
* (C)Copyright 1998,1999 SysKonnect,
* a business unit of Schneider & Koch & Co. Datensysteme GmbH.
*
* See the file "skfddi.c" for further information.
*
* 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 of the License, or
* (at your option) any later version.
*
* The information in this file is provided "AS IS" without warranty.
*
******************************************************************************/
/*
parser for SMT parameters
*/
#include "h/types.h"
#include "h/fddi.h"
#include "h/smc.h"
#include "h/smt_p.h"
#define KERNEL
#include "h/smtstate.h"
#ifndef lint
static const char ID_sccs[] = "@(#)smtparse.c 1.12 98/10/06 (C) SK " ;
#endif
#ifdef sun
#define _far
#endif
/*
* convert to BCLK units
*/
#define MS2BCLK(x) ((x)*12500L)
#define US2BCLK(x) ((x/10)*125L)
/*
* parameter table
*/
static struct s_ptab {
char *pt_name ;
u_short pt_num ;
u_short pt_type ;
u_long pt_min ;
u_long pt_max ;
} ptab[] = {
{ "PMFPASSWD",0, 0 } ,
{ "USERDATA",1, 0 } ,
{ "LERCUTOFFA",2, 1, 4, 15 } ,
{ "LERCUTOFFB",3, 1, 4, 15 } ,
{ "LERALARMA",4, 1, 4, 15 } ,
{ "LERALARMB",5, 1, 4, 15 } ,
{ "TMAX",6, 1, 5, 165 } ,
{ "TMIN",7, 1, 5, 165 } ,
{ "TREQ",8, 1, 5, 165 } ,
{ "TVX",9, 1, 2500, 10000 } ,
#ifdef ESS
{ "SBAPAYLOAD",10, 1, 0, 1562 } ,
{ "SBAOVERHEAD",11, 1, 50, 5000 } ,
{ "MAXTNEG",12, 1, 5, 165 } ,
{ "MINSEGMENTSIZE",13, 1, 0, 4478 } ,
{ "SBACATEGORY",14, 1, 0, 0xffff } ,
{ "SYNCHTXMODE",15, 0 } ,
#endif
#ifdef SBA
{ "SBACOMMAND",16, 0 } ,
{ "SBAAVAILABLE",17, 1, 0, 100 } ,
#endif
{ NULL }
} ;
/* Define maximum string size for values and keybuffer */
#define MAX_VAL 40
/*
* local function declarations
*/
static u_long parse_num(int type, char _far *value, char *v, u_long mn,
u_long mx, int scale);
static int parse_word(char *buf, char _far *text);
#ifdef SIM
#define DB_MAIN(a,b,c) printf(a,b,c)
#else
#define DB_MAIN(a,b,c)
#endif
/*
* BEGIN_MANUAL_ENTRY()
*
* int smt_parse_arg(struct s_smc *,char _far *keyword,int type,
char _far *value)
*
* parse SMT parameter
* *keyword
* pointer to keyword, must be \0, \n or \r terminated
* *value pointer to value, either char * or u_long *
* if char *
* pointer to value, must be \0, \n or \r terminated
* if u_long *
* contains binary value
*
* type 0: integer
* 1: string
* return
* 0 parameter parsed ok
* != 0 error
* NOTE:
* function can be called with DS != SS
*
*
* END_MANUAL_ENTRY()
*/
int smt_parse_arg(struct s_smc *smc, char _far *keyword, int type,
char _far *value)
{
char keybuf[MAX_VAL+1];
char valbuf[MAX_VAL+1];
char c ;
char *p ;
char *v ;
char *d ;
u_long val = 0 ;
struct s_ptab *pt ;
int st ;
int i ;
/*
* parse keyword
*/
if ((st = parse_word(keybuf,keyword)))
return(st) ;
/*
* parse value if given as string
*/
if (type == 1) {
if ((st = parse_word(valbuf,value)))
return(st) ;
}
/*
* search in table
*/
st = 0 ;
for (pt = ptab ; (v = pt->pt_name) ; pt++) {
for (p = keybuf ; (c = *p) ; p++,v++) {
if (c != *v)
break ;
}
if (!c && !*v)
break ;
}
if (!v)
return(-1) ;
#if 0
printf("=>%s<==>%s<=\n",pt->pt_name,valbuf) ;
#endif
/*
* set value in MIB
*/
if (pt->pt_type)
val = parse_num(type,value,valbuf,pt->pt_min,pt->pt_max,1) ;
switch (pt->pt_num) {
case 0 :
v = valbuf ;
d = (char *) smc->mib.fddiPRPMFPasswd ;
for (i = 0 ; i < (signed)sizeof(smc->mib.fddiPRPMFPasswd) ; i++)
*d++ = *v++ ;
DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiPRPMFPasswd) ;
break ;
case 1 :
v = valbuf ;
d = (char *) smc->mib.fddiSMTUserData ;
for (i = 0 ; i < (signed)sizeof(smc->mib.fddiSMTUserData) ; i++)
*d++ = *v++ ;
DB_MAIN("SET %s = %s\n",pt->pt_name,smc->mib.fddiSMTUserData) ;
break ;
case 2 :
smc->mib.p[PA].fddiPORTLer_Cutoff = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PA].fddiPORTLer_Cutoff) ;
break ;
case 3 :
smc->mib.p[PB].fddiPORTLer_Cutoff = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PB].fddiPORTLer_Cutoff) ;
break ;
case 4 :
smc->mib.p[PA].fddiPORTLer_Alarm = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PA].fddiPORTLer_Alarm) ;
break ;
case 5 :
smc->mib.p[PB].fddiPORTLer_Alarm = (u_char) val ;
DB_MAIN("SET %s = %d\n",
pt->pt_name,smc->mib.p[PB].fddiPORTLer_Alarm) ;
break ;
case 6 : /* TMAX */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.a[PATH0].fddiPATHT_MaxLowerBound =
(u_long) -MS2BCLK((long)val) ;
break ;
case 7 : /* TMIN */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.m[MAC0].fddiMACT_Min =
(u_long) -MS2BCLK((long)val) ;
break ;
case 8 : /* TREQ */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.a[PATH0].fddiPATHMaxT_Req =
(u_long) -MS2BCLK((long)val) ;
break ;
case 9 : /* TVX */
DB_MAIN("SET %s = %d \n",pt->pt_name,val) ;
smc->mib.a[PATH0].fddiPATHTVXLowerBound =
(u_long) -US2BCLK((long)val) ;
break ;
#ifdef ESS
case 10 : /* SBAPAYLOAD */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
if (smc->mib.fddiESSPayload != val) {
smc->ess.raf_act_timer_poll = TRUE ;
smc->mib.fddiESSPayload = val ;
}
break ;
case 11 : /* SBAOVERHEAD */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSOverhead = val ;
break ;
case 12 : /* MAXTNEG */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSMaxTNeg = (u_long) -MS2BCLK((long)val) ;
break ;
case 13 : /* MINSEGMENTSIZE */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSMinSegmentSize = val ;
break ;
case 14 : /* SBACATEGORY */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiESSCategory =
(smc->mib.fddiESSCategory & 0xffff) |
((u_long)(val << 16)) ;
break ;
case 15 : /* SYNCHTXMODE */
/* do not use memcmp(valbuf,"ALL",3) because DS != SS */
if (valbuf[0] == 'A' && valbuf[1] == 'L' && valbuf[2] == 'L') {
smc->mib.fddiESSSynchTxMode = TRUE ;
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
}
/* if (!memcmp(valbuf,"SPLIT",5)) { */
if (valbuf[0] == 'S' && valbuf[1] == 'P' && valbuf[2] == 'L' &&
valbuf[3] == 'I' && valbuf[4] == 'T') {
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
smc->mib.fddiESSSynchTxMode = FALSE ;
}
break ;
#endif
#ifdef SBA
case 16 : /* SBACOMMAND */
/* if (!memcmp(valbuf,"START",5)) { */
if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'A' &&
valbuf[3] == 'R' && valbuf[4] == 'T') {
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
smc->mib.fddiSBACommand = SB_START ;
}
/* if (!memcmp(valbuf,"STOP",4)) { */
if (valbuf[0] == 'S' && valbuf[1] == 'T' && valbuf[2] == 'O' &&
valbuf[3] == 'P') {
DB_MAIN("SET %s = %s\n",pt->pt_name,valbuf) ;
smc->mib.fddiSBACommand = SB_STOP ;
}
break ;
case 17 : /* SBAAVAILABLE */
DB_MAIN("SET %s = %d\n",pt->pt_name,val) ;
smc->mib.fddiSBAAvailable = (u_char) val ;
break ;
#endif
}
return(0) ;
}
static int parse_word(char *buf, char _far *text)
{
char c ;
char *p ;
int p_len ;
int quote ;
int i ;
int ok ;
/*
* skip leading white space
*/
p = buf ;
for (i = 0 ; i < MAX_VAL ; i++)
*p++ = 0 ;
p = buf ;
p_len = 0 ;
ok = 0 ;
while ( (c = *text++) && (c != '\n') && (c != '\r')) {
if ((c != ' ') && (c != '\t')) {
ok = 1 ;
break ;
}
}
if (!ok)
return(-1) ;
if (c == '"') {
quote = 1 ;
}
else {
quote = 0 ;
text-- ;
}
/*
* parse valbuf
*/
ok = 0 ;
while (!ok && p_len < MAX_VAL-1 && (c = *text++) && (c != '\n')
&& (c != '\r')) {
switch (quote) {
case 0 :
if ((c == ' ') || (c == '\t') || (c == '=')) {
ok = 1 ;
break ;
}
*p++ = c ;
p_len++ ;
break ;
case 2 :
*p++ = c ;
p_len++ ;
quote = 1 ;
break ;
case 1 :
switch (c) {
case '"' :
ok = 1 ;
break ;
case '\\' :
quote = 2 ;
break ;
default :
*p++ = c ;
p_len++ ;
}
}
}
*p++ = 0 ;
for (p = buf ; (c = *p) ; p++) {
if (c >= 'a' && c <= 'z')
*p = c + 'A' - 'a' ;
}
return(0) ;
}
static u_long parse_num(int type, char _far *value, char *v, u_long mn,
u_long mx, int scale)
{
u_long x = 0 ;
char c ;
if (type == 0) { /* integer */
u_long _far *l ;
u_long u1 ;
l = (u_long _far *) value ;
u1 = *l ;
/*
* if the value is negative take the lower limit
*/
if ((long)u1 < 0) {
if (- ((long)u1) > (long) mx) {
u1 = 0 ;
}
else {
u1 = (u_long) - ((long)u1) ;
}
}
x = u1 ;
}
else { /* string */
int sign = 0 ;
if (*v == '-') {
sign = 1 ;
}
while ((c = *v++) && (c >= '0') && (c <= '9')) {
x = x * 10 + c - '0' ;
}
if (scale == 10) {
x *= 10 ;
if (c == '.') {
if ((c = *v++) && (c >= '0') && (c <= '9')) {
x += c - '0' ;
}
}
}
if (sign)
x = (u_long) - ((long)x) ;
}
/*
* if the value is negative
* and the absolute value is outside the limits
* take the lower limit
* else
* take the absoute value
*/
if ((long)x < 0) {
if (- ((long)x) > (long) mx) {
x = 0 ;
}
else {
x = (u_long) - ((long)x) ;
}
}
if (x < mn)
return(mn) ;
else if (x > mx)
return(mx) ;
return(x) ;
}
#if 0
struct s_smc SMC ;
main()
{
char *p ;
char *v ;
char buf[100] ;
int toggle = 0 ;
while (gets(buf)) {
p = buf ;
while (*p && ((*p == ' ') || (*p == '\t')))
p++ ;
while (*p && ((*p != ' ') && (*p != '\t')))
p++ ;
v = p ;
while (*v && ((*v == ' ') || (*v == '\t')))
v++ ;
if ((*v >= '0') && (*v <= '9')) {
toggle = !toggle ;
if (toggle) {
u_long l ;
l = atol(v) ;
smt_parse_arg(&SMC,buf,0,(char _far *)&l) ;
}
else
smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
}
else {
smt_parse_arg(&SMC,buf,1,(char _far *)p) ;
}
}
exit(0) ;
}
#endif