📄 smend.c
字号:
SM_LOG (SM_DBG_LOAD, "smEndLoad: can't Aallocate SM_END_DEV\n", 0, 0, 0, 0, 0, 0); return ((END_OBJ *)ERROR); } /* validate structure */ pSmEndDev->cookie = SM_END_COOKIE; /* * Parse the initialization parameter string, extracting all parameters. * Parameter values are delimited by spaces. */ SM_LOG (SM_DBG_LOAD, "Parsing string...\n", 0, 0, 0, 0, 0, 0); if (smEndParse (pSmEndDev, pParamStr) != ERROR) { /* * The <ticksPerBeat> parameter specifies the frequency of the shared * memory anchor's heartbeat. The frequency is expressed in terms of * the number of CPU ticks on the local CPU corresponding to one * heartbeat period. */ pSmEndDev->ticksPerBeat = sysClkRateGet (); /* if initial mode is polled, lock it */ if (pSmEndDev->intType == SM_INT_NONE) pSmEndDev->flags = S_POLLED_SM_LOCKED; else pSmEndDev->flags = 0; /* If not already, allocate unit table and store our ptr in it */ if (unitTbl != NULL) { if ((unitTbl = (SM_END_DEV **)calloc (NSM, sizeof (SM_END_DEV))) == NULL) { smEndUnload (pSmEndDev); return ((END_OBJ *)ERROR); } } unitTbl [pSmEndDev->unit] = pSmEndDev; /* If this is the master CPU, determine addressing mode */ if (pSmEndDev->masterCpu == smUtilProcNumGet ()) { pSmEndDev->isMaster = TRUE; if (pSmEndDev->startAddr != NULL) { SM_LOG (SM_DBG_LOAD, "MASTER: sequential addressing enabled at (0x%x)\n", (unsigned)pSmEndDev->startAddr, 0, 0, 0, 0, 0); } else { SM_LOG (SM_DBG_LOAD, "MASTER: sequential addressing disabled\n", 0, 0, 0, 0, 0, 0); } } /* Perform device memory allocation/distribution */ if (smEndMemInit (pSmEndDev) == ERROR) { smEndUnload (pSmEndDev); return ((END_OBJ *)ERROR); } /* Initialize the shared memory descriptor. */ pAnchor = pSmEndDev->pAnchor; smPktInit (&pSmEndDev->smPktDesc, pSmEndDev->pAnchor, pSmEndDev->maxPackets, pSmEndDev->ticksPerBeat, pSmEndDev->intType, pSmEndDev->intArg1, pSmEndDev->intArg2, pSmEndDev->intArg3); pSmEndDev->smPktDesc.hdrLocalAdrs = pSmEndDev->pSmPktHdr; /* initialize the END and MIB2 parts of the device structure */ if ((END_OBJ_INIT (&pSmEndDev->end, (DEV_OBJ *)pSmEndDev, SM_END_DEV_NAME, pSmEndDev->unit, &smEndFuncTable, "Shared Memory END Driver") != ERROR) && (END_MIB_INIT (&pSmEndDev->end, M2_ifType_other, enetAddr, EADDR_LEN, SM_END_CLST_SIZ, SM_END_MIB2_SPEED) != ERROR)) { /* configure the device */ smEndConfig (pSmEndDev, SC_INIT); /* XXX * The following code is a hack. The anchor may not even be * mapped to the bus yet! When probing with the next few lines * Bus Errors occur 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. Towards this end an initial * delay in bus probing is introduced based on processor number. * If the first probe is unsuccessful, an exponential increase in * delay period is used to reduce bus contention on subsequent * probes. This workaround is no worse than receiving BERRs * but does reduce bus contention and the number of BERRs. Note * that the master procesor is assumed to be processor #0 (even * though it may not be). Processor #0 has no effective delay * period on the first or subsequent bus probes! This is so the * presumed master processor can proceed with minimal delay. */ for (tics <<= 1; (tics < SM_MAX_WAIT) && (anchorSet == ERROR); tics <<= 1) { smUtilDelay (NULL, tics); if ((anchorSet = smUtilMemProbe ((char *)pAnchor, READ, 4, (char *)&temp)) != OK) continue; } if (tics >= SM_MAX_WAIT) { SM_LOG (SM_DBG_LOAD, "smEndLoad: Error: sm probe timed out\n", 0, 0, 0, 0, 0, 0); smEndUnload (pSmEndDev); return ((END_OBJ *)ERROR); } SM_LOG (SM_DBG_LOAD, "smEndLoad: sm probe worked, tics = %u\n", tics, 0, 0, 0, 0, 0); /* * IP -> HW Address Resolution * Whether or not sequential addressing is enabled, we calculate * the HW address. ARP protocol does not apply. */ muxAddrResFuncAdd (M2_ifType_other, 0x800, smEndAddrResolve); /* set the flags to indicate readiness */ SM_RCV_TASK_INACTIVE; END_OBJ_READY (&pSmEndDev->end, smEndDevAttr); pSmEndDev->flags |= S_ACTIVE; SM_LOG (SM_DBG_LOAD, "Done loading smEnd - flags = %#lx\n", pSmEndDev->flags, 0, 0, 0, 0, 0); return (&pSmEndDev->end); } } smEndUnload (pSmEndDev); return ((END_OBJ *)ERROR); }/********************************************************************************* smEndUnload - unload sm device from the system** This routine unloads the device pointed to by <pSmEndDev> from the system.** RETURNS: OK or ERROR.** SEE ALSO: smEndLoad()*/LOCAL STATUS smEndUnload ( void * pObj /* device control pointer */ ) { unsigned i; unsigned cnt; SM_END_DEV * pSmEndDev = (SM_END_DEV *)pObj; SM_PKT_MEM_HDR * pSmPktHdr = NULL; /* packet header */ SM_LOG (SM_DBG_UNLOAD, "smEndUnload: start\n", 0, 0, 0, 0, 0, 0); if (pSmEndDev == NULL) { SM_LOG (SM_DBG_UNLOAD, "smEndUnload error: NULL device pointer\n", 0, 0, 0, 0, 0, 0); return (ERROR); } /* been there, done that... */ if (pSmEndDev->cookie != SM_END_COOKIE) { SM_LOG (SM_DBG_UNLOAD, "smEndUnload warning: dev already unloaded\n", 0, 0, 0, 0, 0, 0); return (OK); }#ifdef SM_DBG if (!SM_END_IS_LOADED) { SM_LOG (SM_DBG_UNLOAD, "smEndUnload warning: device not loaded\n", 0, 0, 0, 0, 0, 0); }#endif /* SM_DBG */ SM_END_UNLOAD; /* detach from shared mem */ if (pSmEndDev->smPktDesc.status == SM_CPU_ATTACHED) { (void) smPktDetach (&pSmEndDev->smPktDesc, SM_FLUSH); } /* clear END status flags */ END_FLAGS_CLR (&pSmEndDev->end, SM_END_ATTR_CLR); pSmEndDev->flags = 0; /* finished with END object */ END_OBJECT_UNLOAD (&pSmEndDev->end); /* free allocated memory as necessary */ if (pSmEndDev->tupleId != NULL) netMblkClChainFree (pSmEndDev->tupleId); if (pSmEndDev->end.pNetPool != NULL) netPoolDelete (pSmEndDev->end.pNetPool); if (pSmEndDev->pClustMem != NULL) cacheDmaFree (pSmEndDev->pClustMem); if (pSmEndDev->pMclBlkCfg != NULL) free (pSmEndDev->pMclBlkCfg); if (pSmEndDev->end.pNetPool != NULL) free (pSmEndDev->end.pNetPool); /* * If this is the master CPU, delete heartbeat watchdog timer * and free shared memory if it was allocated. */ if (pSmEndDev->isMaster) { pSmPktHdr = SM_OFFSET_TO_LOCAL (ntohl(pSmEndDev->pAnchor->smPktHeader), (int)pSmEndDev->pAnchor, SM_PKT_MEM_HDR *); if (pSmPktHdr->reserved2 != 0) { wdDelete ((WDOG_ID) ntohl (pSmPktHdr->reserved2)); } if (pSmEndDev->smAlloc) cacheDmaFree (pSmEndDev->pMem); } /* invalidate structure */ pSmEndDev->cookie = 0; /* if this is the last entry in the unit table, free the table */ for (i = 0, cnt = 0; i < NSM; ++i) { if (unitTbl[i] == pSmEndDev) unitTbl[i] = NULL; else ++cnt; } if (cnt == 0) free (unitTbl); /* free memory for device control structure */ free (pSmEndDev); pSmEndDev = NULL; SM_LOG (SM_DBG_UNLOAD, "smEndUnload: Done\n", 0, 0, 0, 0, 0, 0); return (OK); }/******************************************************************************** smEndConfig - configure the sm interface to the device** Configure the interface through controlled state changes.** RETURNS: OK or ERROR.*/LOCAL STATUS smEndConfig ( SM_END_DEV * pSmEndDev, /* device to be configured */ STATE_CHANGE sDelta /* type of configuration change */ ) { STATUS result = OK; /* shutdown device completely if attached and reclaim packets */ if (pSmEndDev->smPktDesc.status == SM_CPU_ATTACHED) { (void) smPktDetach (&pSmEndDev->smPktDesc, SM_FLUSH); pSmEndDev->smPktDesc.status = 0; pSmEndDev->flags &= ~S_CPU_ATTACHED; } /* Perform requested state change */ switch (sDelta) { case SC_INT2POLL: if (pollTaskId == NONE) { if ((result = smUtilIntConnect (LOW_PRIORITY,(FUNCPTR)smEndIsr, (int)pSmEndDev, SM_INT_NONE, 0, 0, 0)) == OK) { connected[SM_INT_NONE] = TRUE; pollTaskId = taskNameToId (SM_POLL_TASK_NAME); } } else { result = taskResume (pollTaskId); } break; case SC_POLL2INT: if (pollTaskId == NONE) { errno = EINVAL; result = ERROR; } else { taskSuspend (pollTaskId); if ((!connected[pSmEndDev->intType]) && (result = smUtilIntConnect (LOW_PRIORITY, (FUNCPTR)smEndIsr, (int)pSmEndDev, pSmEndDev->intType, pSmEndDev->intArg1, pSmEndDev->intArg2, pSmEndDev->intArg3)) == OK) { connected[pSmEndDev->intType] = TRUE; } } break; case SC_INIT: /* set hardware address */ smEndHwAddrSet (pSmEndDev); break; case SC_NONE: break; default: SM_LOG (SM_DBG_CFG, "smEndConfig: unknown state change %x\n", sDelta, 0, 0, 0, 0, 0); errno = EINVAL; result = ERROR; }#if FALSE /* XXXmas future enhancement */ /* set up address filter for multicasting */ if (END_MULTI_LST_CNT(&pSmEndDev->end) > 0) { smEndAddrFilterSet (pSmEndDev); }#endif /* attach to shared memory */ if (smPktAttach (&pSmEndDev->smPktDesc) == ERROR) { SM_LOG (SM_DBG_CFG, "smEndConfig: ERROR attaching to sm: 0x%x\n", errno, 0, 0, 0, 0, 0); smEndUnload (pSmEndDev); /* ??? is this necessary? */ return (ERROR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -