aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/skfp/smtparse.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 15:20:36 -0700
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/skfp/smtparse.c
Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/skfp/smtparse.c')
-rw-r--r--drivers/net/skfp/smtparse.c467
1 files changed, 467 insertions, 0 deletions
diff --git a/drivers/net/skfp/smtparse.c b/drivers/net/skfp/smtparse.c
new file mode 100644
index 00000000000..d5779e414db
--- /dev/null
+++ b/drivers/net/skfp/smtparse.c
@@ -0,0 +1,467 @@
+/******************************************************************************
+ *
+ * (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
+