📄 smnetlib.c
字号:
int intArg3 /* interrupt argument #3 */ ) { SM_SOFTC * xs; /* softc pointer */ SM_PKT_MEM_HDR * pSmPktHdr; /* packet header */ int temp; /* XXX for vxMemProbe */ if (unit >= NSM) return (ERROR); if ((xs = (SM_SOFTC *) calloc (sizeof (SM_SOFTC), 1)) == NULL) return (ERROR); sm_softc [unit] = xs; if (smIfAttach (unit, pAnchor, maxInputPkts, intType, intArg1, intArg2, intArg3, sysClkRateGet (), smNetLoanNum) == OK) { /* XXX * The following code is out of place. The anchor may not even be * mapped to the bus yet! When poking around with the next few lines * you get a BERR on many boards if the slave beats the master to the * pool. The hack here simply avoids the sequential addressing if * the slave gets a BERR looking for the anchor. Therefore, reliable * use of sequential addressing can only be guaranteed if the slave * is stopped during the booting sequence until the master has fully * booted. This workaround is no worse than receiving the BERR * though perhaps only marginally better. */ if ((vxMemProbe ((char *)pAnchor, READ, 4, (char *) &temp)) == OK) { pSmPktHdr = SM_OFFSET_TO_LOCAL (ntohl (pAnchor->smPktHeader), xs->smPktDesc.smDesc.base, SM_PKT_MEM_HDR *); /* sequential addressing - can calculate hw address */ if (pSmPktHdr->reserved1 != 0) xs->xs_ac.ac_if.if_resolve = smNetAddrResolve; } xs->taskRecvActive = FALSE; if (smUtilIntConnect (LOW_PRIORITY, (FUNCPTR) smNetIntr, intType, intType, intArg1, intArg2, intArg3) == OK) return (OK); if_dettach (&xs->xs_if); } (void) free ((caddr_t) xs); return (ERROR); }/********************************************************************************* smNetIntr - VxWorks interrupt service routine** This routine is the interrupt service routine for shared memory input* packets. It processes the interrupt (if appropriate) then notifies the* interface of the incomming packet by calling smIfInput via the netTask.** RETURNS: N/A*/LOCAL void smNetIntr ( int intType /* interrupt type */ ) { SM_SOFTC * xs; /* softc pointer */ int ix; /* unit */ for (ix = 0; ix < NSM; ix++) { if (((xs = sm_softc [ix]) != NULL) && (xs->smPktDesc.status == SM_CPU_ATTACHED) && (smIfInputCount (xs, xs->smPktDesc.smDesc.cpuNum) > 0)) { if (!xs->taskRecvActive) { xs->taskRecvActive = TRUE; (void) netJobAdd ((FUNCPTR) smIfInput, (int) xs, 0, 0, 0, 0); } } if ((xs != NULL) && (intType == SM_INT_BUS)) /* bus interrupt */ sysBusIntAck (xs->smPktDesc.smDesc.intArg1); } }/********************************************************************************* smNetPulse - continually pulse the shared memory heartbeat** This routine maintains the shared memory heart beat by incrementing * the heartbeat count and then re-scheduling itself to run again * after a "beat" has passed.** RETURNS: N/A*/LOCAL void smNetPulse ( SM_PKT_MEM_HDR * pSmPktHdr /* pointer to heartbeat */ ) { smPktBeat (pSmPktHdr); (void) wdStart ((WDOG_ID) pSmPktHdr->reserved2, (int) sysClkRateGet (), (FUNCPTR) smNetPulse, (int) pSmPktHdr); }/********************************************************************************* loanBuild - build an mbuf cluster with a shared memory buffer** This routine calls build cluster to build an mbuf cluster from a shared* memory packet.** RETURNS: pointer to the cluster if successful, otherwise NULL** NOMANUAL*/struct mbuf * loanBuild ( SM_SOFTC * xs, /* softc pointer */ SM_PKT * pPkt, /* shared memory packet */ u_char * pData, /* pointer to data */ int len /* length of packet */ ) { pPkt->header.type = 0; return (build_cluster (pData, len, &xs->xs_if, MC_BACKPLANE, &(pPkt->header.type), smIfLoanReturn, (int) xs, (int) pPkt, NULL)); }/********************************************************************************* smNetInetGet - get an address associated with a shared memory network interface** This routine returns the Internet address in <smInet> for the CPU* specified by <cpuNum> on the shared memory network specified by <smName>.* If <cpuNum> is NONE (-1), this routine returns information about the local* (calling) CPU.** This routine can only be called after a call to smNetAttach(). It will* block if the shared memory region has not yet been initialized.** This routine is only applicable if sequential addressing is being used* over the backplane.** RETURNS: OK, or ERROR if the Internet address cannot be found.*/STATUS smNetInetGet ( char * smName, /* device name */ char * smInet, /* return inet */ int cpuNum /* cpu number */ ) { SM_SOFTC * xs; /* softc pointer */ SM_ANCHOR * pAnchor; /* ptr to anchor */ SM_PKT_MEM_HDR * pSmPktHdr; /* packet header */ struct in_addr smAddr; /* address */ if ((xs = (SM_SOFTC *) ifunit (smName)) == NULL) { printf ("smNetInetGet:%s not attached\n", smName); return (ERROR); } pAnchor = xs->smPktDesc.smDesc.anchorLocalAdrs; if (smIsAlive (pAnchor, &pAnchor->smPktHeader, xs->smPktDesc.smDesc.base, 0, 0) == FALSE) return (ERROR); pSmPktHdr = SM_OFFSET_TO_LOCAL (ntohl (pAnchor->smPktHeader), xs->smPktDesc.smDesc.base, SM_PKT_MEM_HDR *); if (pSmPktHdr->reserved1 == 0) /* no sequential addressing */ return (ERROR); if (cpuNum == NONE) cpuNum = xs->smPktDesc.smDesc.cpuNum; smAddr.s_addr = htonl (ntohl (pSmPktHdr->reserved1) + cpuNum); inet_ntoa_b (smAddr, smInet); return (OK); }/********************************************************************************* smNetAddrResolve - resolve an Ethernet address** This routine converts a destination IP address into a destination* Ethernet address. It only resolves the address if sequential addressing* is being used and the destination is attached to shared memory.** RETURNS: OK if successful, otherwise ERROR.*/LOCAL STATUS smNetAddrResolve ( FAST struct ifnet * pIf, /* ifnet pointer */ FAST struct in_addr * pIpDest, /* dest ip address */ FAST u_char * pHwDest, /* return hardware adddess */ int * usetrailers /* not used */ ) { SM_PKT_CPU_DESC * pPktCpuDesc; u_long dstHostAddr; int destCpu; SM_SOFTC * xs = sm_softc [pIf->if_unit];/* softc pointer */ if (xs->masterAddr == 0) return (ERROR); /* sequential addressing not enabled */ dstHostAddr = pIpDest->s_addr & 0x00ffffff; destCpu = dstHostAddr - xs->masterAddr; if ((destCpu < 0) || (destCpu >= xs->smPktDesc.smDesc.maxCpus)) return (ERROR); pPktCpuDesc = &((xs->smPktDesc.cpuLocalAdrs) [destCpu]); if (pPktCpuDesc->status != SM_CPU_ATTACHED) return (ERROR); pHwDest [0] = 0x00; /* concoct enet address */ pHwDest [1] = 0x02; pHwDest [2] = 0xE2; pHwDest [3] = (dstHostAddr >> 16) & 0xff; pHwDest [4] = (dstHostAddr >> 8) & 0xff; pHwDest [5] = dstHostAddr & 0xff; /* entered into arp table for efficency */ arpCmd (SIOCSARP, pIpDest, pHwDest, NULL); *usetrailers = 0; return (OK); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -