📄 pmf.c
字号:
if (mac < 0 || mac >= NUMMACS) { return(SMT_RDF_NOPARAM) ; } mib_m = &smc->mib.m[mac] ; mib_addr = (char *) mib_m ; from += 4 ; /* skip index */ len -= 4 ; break ; case 0x3000 : if (path < 0 || path >= NUMPATHS) { return(SMT_RDF_NOPARAM) ; } mib_a = &smc->mib.a[path] ; mib_addr = (char *) mib_a ; from += 4 ; /* skip index */ len -= 4 ; break ; case 0x4000 : if (port < 0 || port >= smt_mib_phys(smc)) { return(SMT_RDF_NOPARAM) ; } mib_p = &smc->mib.p[port_to_mib(smc,port)] ; mib_addr = (char *) mib_p ; from += 4 ; /* skip index */ len -= 4 ; break ; } switch (pa->p_type) { case SMT_P10F0 : case SMT_P10F1 :#ifdef ESS case SMT_P10F2 : case SMT_P10F3 : case SMT_P10F4 : case SMT_P10F5 : case SMT_P10F6 : case SMT_P10F7 :#endif#ifdef SBA case SMT_P10F8 : case SMT_P10F9 :#endif case SMT_P20F1 : if (!local) { return(SMT_RDF_NOPARAM) ; } break ; } pt = smt_get_ptab(pa->p_type) ; if (!pt) { return( (pa->p_type & 0xff00) ? SMT_RDF_NOPARAM : SMT_RDF_ILLEGAL ) ; } switch (pt->p_access) { case AC_GR : case AC_S : break ; default : return(SMT_RDF_ILLEGAL) ; } to = mib_addr + pt->p_offset ; swap = pt->p_swap ; /* pointer to swap string */ while (swap && (c = *swap++)) { switch(c) { case 'b' : to = (char *) &byte_val ; break ; case 'w' : to = (char *) &word_val ; break ; case 'l' : to = (char *) &long_val ; break ; case 'S' : case 'E' : case 'R' : case 'r' : if (len < 4) { goto len_error ; } if (from[0] | from[1]) goto val_error ;#ifdef LITTLE_ENDIAN if (c == 'r') { to[0] = from[2] ; to[1] = from[3] ; } else { to[1] = from[2] ; to[0] = from[3] ; }#else to[0] = from[2] ; to[1] = from[3] ;#endif from += 4 ; to += 2 ; len -= 4 ; break ; case 'F' : case 'B' : if (len < 4) { goto len_error ; } if (from[0] | from[1] | from[2]) goto val_error ; to[0] = from[3] ; len -= 4 ; from += 4 ; to += 4 ; break ; case 'C' : case 'T' : case 'L' : if (len < 4) { goto len_error ; }#ifdef LITTLE_ENDIAN to[3] = *from++ ; to[2] = *from++ ; to[1] = *from++ ; to[0] = *from++ ;#else to[0] = *from++ ; to[1] = *from++ ; to[2] = *from++ ; to[3] = *from++ ;#endif len -= 4 ; to += 4 ; break ; case 'A' : if (len < 8) goto len_error ; if (set) memcpy((char *) to,(char *) from+2,6) ; to += 8 ; from += 8 ; len -= 8 ; break ; case '4' : if (len < 4) goto len_error ; if (set) memcpy((char *) to,(char *) from,4) ; to += 4 ; from += 4 ; len -= 4 ; break ; case '8' : if (len < 8) goto len_error ; if (set) memcpy((char *) to,(char *) from,8) ; to += 8 ; from += 8 ; len -= 8 ; break ; case 'D' : if (len < 32) goto len_error ; if (set) memcpy((char *) to,(char *) from,32) ; to += 32 ; from += 32 ; len -= 32 ; break ; case 'P' : /* timestamp is NOT swapped */ if (set) { to[0] = *from++ ; to[1] = *from++ ; to[2] = *from++ ; to[3] = *from++ ; to[4] = *from++ ; to[5] = *from++ ; to[6] = *from++ ; to[7] = *from++ ; } to += 8 ; len -= 8 ; break ; default : SMT_PANIC(smc,SMT_E0120, SMT_E0120_MSG) ; return(SMT_RDF_ILLEGAL) ; } } /* * actions and internal updates */ switch (pa->p_type) { case SMT_P101A: /* fddiSMTConfigPolicy */ if (word_val & ~1) goto val_error ; IFSET(mib->fddiSMTConfigPolicy = word_val) ; break ; case SMT_P101B : /* fddiSMTConnectionPolicy */ if (!(word_val & POLICY_MM)) goto val_error ; IFSET(mib->fddiSMTConnectionPolicy = word_val) ; break ; case SMT_P101D : /* fddiSMTTT_Notify */ if (word_val < 2 || word_val > 30) goto val_error ; IFSET(mib->fddiSMTTT_Notify = word_val) ; break ; case SMT_P101E : /* fddiSMTStatRptPolicy */ if (byte_val & ~1) goto val_error ; IFSET(mib->fddiSMTStatRptPolicy = byte_val) ; break ; case SMT_P101F : /* fddiSMTTrace_MaxExpiration */ /* * note: lower limit trace_max = 6.001773... s * NO upper limit */ if (long_val < (long)0x478bf51L) goto val_error ; IFSET(mib->fddiSMTTrace_MaxExpiration = long_val) ; break ;#ifdef ESS case SMT_P10F2 : /* fddiESSPayload */ if (long_val > 1562) goto val_error ; if (set && smc->mib.fddiESSPayload != long_val) { smc->ess.raf_act_timer_poll = TRUE ; smc->mib.fddiESSPayload = long_val ; } break ; case SMT_P10F3 : /* fddiESSOverhead */ if (long_val < 50 || long_val > 5000) goto val_error ; if (set && smc->mib.fddiESSPayload && smc->mib.fddiESSOverhead != long_val) { smc->ess.raf_act_timer_poll = TRUE ; smc->mib.fddiESSOverhead = long_val ; } break ; case SMT_P10F4 : /* fddiESSMaxTNeg */ if (long_val > -MS2BCLK(5) || long_val < -MS2BCLK(165)) goto val_error ; IFSET(mib->fddiESSMaxTNeg = long_val) ; break ; case SMT_P10F5 : /* fddiESSMinSegmentSize */ if (long_val < 1 || long_val > 4478) goto val_error ; IFSET(mib->fddiESSMinSegmentSize = long_val) ; break ; case SMT_P10F6 : /* fddiESSCategory */ if ((long_val & 0xffff) != 1) goto val_error ; IFSET(mib->fddiESSCategory = long_val) ; break ; case SMT_P10F7 : /* fddiESSSyncTxMode */ if (word_val > 1) goto val_error ; IFSET(mib->fddiESSSynchTxMode = word_val) ; break ;#endif#ifdef SBA case SMT_P10F8 : /* fddiSBACommand */ if (byte_val != SB_STOP && byte_val != SB_START) goto val_error ; IFSET(mib->fddiSBACommand = byte_val) ; break ; case SMT_P10F9 : /* fddiSBAAvailable */ if (byte_val > 100) goto val_error ; IFSET(mib->fddiSBAAvailable = byte_val) ; break ;#endif case SMT_P2020 : /* fddiMACRequestedPaths */ if ((word_val & (MIB_P_PATH_PRIM_PREFER | MIB_P_PATH_PRIM_ALTER)) == 0 ) goto val_error ; IFSET(mib_m->fddiMACRequestedPaths = word_val) ; break ; case SMT_P205F : /* fddiMACFrameErrorThreshold */ /* 0 .. ffff acceptable */ IFSET(mib_m->fddiMACFrameErrorThreshold = word_val) ; break ; case SMT_P2067 : /* fddiMACNotCopiedThreshold */ /* 0 .. ffff acceptable */ IFSET(mib_m->fddiMACNotCopiedThreshold = word_val) ; break ; case SMT_P2076: /* fddiMACMA_UnitdataEnable */ if (byte_val & ~1) goto val_error ; if (set) { mib_m->fddiMACMA_UnitdataEnable = byte_val ; queue_event(smc,EVENT_RMT,RM_ENABLE_FLAG) ; } break ; case SMT_P20F1 : /* fddiMACT_Min */ IFSET(mib_m->fddiMACT_Min = long_val) ; break ; case SMT_P320F : if (long_val > 1562) goto val_error ; IFSET(mib_a->fddiPATHSbaPayload = long_val) ;#ifdef ESS if (set) ess_para_change(smc) ;#endif break ; case SMT_P3210 : if (long_val > 5000) goto val_error ; if (long_val != 0 && mib_a->fddiPATHSbaPayload == 0) goto val_error ; IFSET(mib_a->fddiPATHSbaOverhead = long_val) ;#ifdef ESS if (set) ess_para_change(smc) ;#endif break ; case SMT_P3213: /* fddiPATHT_Rmode */ /* no limit : * 0 .. 343.597 => 0 .. 2e32 * 80nS */ if (set) { mib_a->fddiPATHT_Rmode = long_val ; rtm_set_timer(smc) ; } break ; case SMT_P3214 : /* fddiPATHSbaAvailable */ if (long_val > 0x00BEBC20L) goto val_error ;#ifdef SBA if (set && mib->fddiSBACommand == SB_STOP) goto val_error ;#endif IFSET(mib_a->fddiPATHSbaAvailable = long_val) ; break ; case SMT_P3215 : /* fddiPATHTVXLowerBound */ IFSET(mib_a->fddiPATHTVXLowerBound = long_val) ; goto change_mac_para ; case SMT_P3216 : /* fddiPATHT_MaxLowerBound */ IFSET(mib_a->fddiPATHT_MaxLowerBound = long_val) ; goto change_mac_para ; case SMT_P3217 : /* fddiPATHMaxT_Req */ IFSET(mib_a->fddiPATHMaxT_Req = long_val) ;change_mac_para: if (set && smt_set_mac_opvalues(smc)) { RS_SET(smc,RS_EVENT) ; smc->sm.please_reconnect = 1 ; queue_event(smc,EVENT_ECM,EC_DISCONNECT) ; } break ; case SMT_P400E : /* fddiPORTConnectionPolicies */ if (byte_val > 1) goto val_error ; IFSET(mib_p->fddiPORTConnectionPolicies = byte_val) ; break ; case SMT_P4011 : /* fddiPORTRequestedPaths */ /* all 3*8 bits allowed */ IFSET(memcpy((char *)mib_p->fddiPORTRequestedPaths, (char *)&long_val,4)) ; break ; case SMT_P401F: /* fddiPORTMaint_LS */ if (word_val > 4) goto val_error ; IFSET(mib_p->fddiPORTMaint_LS = word_val) ; break ; case SMT_P403A : /* fddiPORTLer_Cutoff */ if (byte_val < 4 || byte_val > 15) goto val_error ; IFSET(mib_p->fddiPORTLer_Cutoff = byte_val) ; break ; case SMT_P403B : /* fddiPORTLer_Alarm */ if (byte_val < 4 || byte_val > 15) goto val_error ; IFSET(mib_p->fddiPORTLer_Alarm = byte_val) ; break ; /* * Actions */ case SMT_P103C : /* fddiSMTStationAction */ if (smt_action(smc,SMT_STATION_ACTION, (int) word_val, 0)) goto val_error ; break ; case SMT_P4046: /* fddiPORTAction */ if (smt_action(smc,SMT_PORT_ACTION, (int) word_val, port_to_mib(smc,port))) goto val_error ; break ; default : break ; } return(0) ;val_error: /* parameter value in frame is out of range */ return(SMT_RDF_RANGE) ;len_error: /* parameter value in frame is too short */ return(SMT_RDF_LENGTH) ;#if 0no_author_error: /* parameter not setable, because the SBA is not active * Please note: we give the return code 'not authorizeed * because SBA denied is not a valid return code in the * PMF protocol. */ return(SMT_RDF_AUTHOR) ;#endif}static const struct s_p_tab *smt_get_ptab(u_short para){ const struct s_p_tab *pt ; for (pt = p_tab ; pt->p_num && pt->p_num != para ; pt++) ; return(pt->p_num ? pt : NULL) ;}static int smt_mib_phys(struct s_smc *smc){#ifdef CONCENTRATOR SK_UNUSED(smc) ; return(NUMPHYS) ;#else if (smc->s.sas == SMT_SAS) return(1) ; return(NUMPHYS) ;#endif}int port_to_mib(struct s_smc *smc, int p){#ifdef CONCENTRATOR SK_UNUSED(smc) ; return(p) ;#else if (smc->s.sas == SMT_SAS) return(PS) ; return(p) ;#endif}#ifdef DEBUG#ifndef BOOTvoid dump_smt(struct s_smc *smc, struct smt_header *sm, char *text){ int len ; struct smt_para *pa ; char *c ; int n ; int nn ;#ifdef LITTLE_ENDIAN int smtlen ;#endif SK_UNUSED(smc) ;#ifdef DEBUG_BRD if (smc->debug.d_smtf < 2)#else if (debug.d_smtf < 2)#endif return ;#ifdef LITTLE_ENDIAN smtlen = sm->smt_len + sizeof(struct smt_header) ;#endif printf("SMT Frame [%s]:\nDA ",text) ; dump_hex((char *) &sm->smt_dest,6) ; printf("\tSA ") ; dump_hex((char *) &sm->smt_source,6) ; printf(" Class %x Type %x Version %x\n", sm->smt_class,sm->smt_type,sm->smt_version) ; printf("TID %lx\t\tSID ",sm->smt_tid) ; dump_hex((char *) &sm->smt_sid,8) ; printf(" LEN %x\n",sm->smt_len) ; len = sm->smt_len ; pa = (struct smt_para *) (sm + 1) ; while (len > 0 ) { int plen ;#ifdef UNIX printf("TYPE %x LEN %x VALUE\t",pa->p_type,pa->p_len) ;#else printf("TYPE %04x LEN %2x VALUE\t",pa->p_type,pa->p_len) ;#endif n = pa->p_len ; if ( (n < 0 ) || (n > (int)(len - PARA_LEN))) { n = len - PARA_LEN ; printf(" BAD LENGTH\n") ; break ; }#ifdef LITTLE_ENDIAN smt_swap_para(sm,smtlen,0) ;#endif if (n < 24) { dump_hex((char *)(pa+1),(int) n) ; printf("\n") ; } else { int first = 0 ; c = (char *)(pa+1) ; dump_hex(c,16) ; printf("\n") ; n -= 16 ; c += 16 ; while (n > 0) { nn = (n > 16) ? 16 : n ; if (n > 64) { if (first == 0) printf("\t\t\t...\n") ; first = 1 ; } else { printf("\t\t\t") ; dump_hex(c,nn) ; printf("\n") ; } n -= nn ; c += 16 ; } }#ifdef LITTLE_ENDIAN smt_swap_para(sm,smtlen,1) ;#endif plen = (pa->p_len + PARA_LEN + 3) & ~3 ; len -= plen ; pa = (struct smt_para *)((char *)pa + plen) ; } printf("-------------------------------------------------\n\n") ;}void dump_hex(char *p, int len){ int n = 0 ; while (len--) { n++ ;#ifdef UNIX printf("%x%s",*p++ & 0xff,len ? ( (n & 7) ? " " : "-") : "") ;#else printf("%02x%s",*p++ & 0xff,len ? ( (n & 7) ? " " : "-") : "") ;#endif }}#endif /* no BOOT */#endif /* DEBUG */#endif /* no SLIM_SMT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -