static int __init EplLinInit(void) { tEplKernel EplRet; int iErr; int iRet; TRACE0("EPL: + EplLinInit...\n"); TRACE2("EPL: Driver build: %s / %s\n", __DATE__, __TIME__); iRet = 0; // initialize global variables atomic_set(&AtomicEventState_g, EVENT_STATE_INIT); sema_init(&SemaphoreCbEvent_g, 1); init_waitqueue_head(&WaitQueueCbEvent_g); init_waitqueue_head(&WaitQueueProcess_g); init_waitqueue_head(&WaitQueueRelease_g); // register character device handler // only one Minor required TRACE2("EPL: Installing Driver '%s', Version %s...\n", EPLLIN_DRV_NAME, EPL_PRODUCT_VERSION); iRet = alloc_chrdev_region(&nDevNum_g, 0, 1, EPLLIN_DRV_NAME); if (iRet == 0) { TRACE2 ("EPL: Driver '%s' installed successful, assigned MajorNumber=%d\n", EPLLIN_DRV_NAME, MAJOR(nDevNum_g)); } else { TRACE1 ("EPL: ERROR: Driver '%s' is unable to get a free MajorNumber!\n", EPLLIN_DRV_NAME); iRet = -EIO; goto Exit; } // register cdev structure pEpl_cdev_g = cdev_alloc(); pEpl_cdev_g->ops = &EplLinFileOps_g; pEpl_cdev_g->owner = THIS_MODULE; iErr = cdev_add(pEpl_cdev_g, nDevNum_g, 1); if (iErr) { TRACE2("EPL: ERROR %d: Driver '%s' could not be added!\n", iErr, EPLLIN_DRV_NAME); iRet = -EIO; goto Exit; } // create device node in PROCFS EplRet = EplLinProcInit(); if (EplRet != kEplSuccessful) { goto Exit; } Exit: TRACE1("EPL: - EplLinInit (iRet=%d)\n", iRet); return (iRet); }
static int __init EplLinInit (void) { tEplKernel EplRet; int iErr; int iRet; #ifdef CONFIG_DEVFS_FS int nMinorNumber; #endif TRACE0("EPL: + EplLinInit...\n"); TRACE2("EPL: Driver build: %s / %s\n", __DATE__, __TIME__); iRet = 0; // initialize global variables atomic_set(&AtomicEventState_g, EVENT_STATE_INIT); sema_init(&SemaphoreCbEvent_g, 1); init_waitqueue_head(&WaitQueueCbEvent_g); init_waitqueue_head(&WaitQueueProcess_g); init_waitqueue_head(&WaitQueueRelease_g); // register misc device iErr = misc_register(&EplLinMiscDevice_g); if (iErr == 0) { TRACE1("EPL: Misc device '%s' created successfully.\n", EPLLIN_DEV_NAME); } else { printk("EPL: ERROR: unable to create misc device '%s'\n", EPLLIN_DEV_NAME); iRet = -EIO; goto Exit; } // create device node in PROCFS EplRet = EplLinProcInit(); if (EplRet != kEplSuccessful) { iRet = -EIO; goto Exit; } Exit: TRACE1("EPL: - EplLinInit (iRet=%d)\n", iRet); return (iRet); }
//--------------------------------------------------------------------------- // // Function: EplLinInit // // Description: Entry point of kernel module //// // // Parameters: N/A // // // Returns: Return code // //--------------------------------------------------------------------------- static int __init EplLinInit (void) { tEplKernel EplRet; static tEplApiInitParam EplApiInitParam = {0}; char* sHostname = HOSTNAME; BOOL fApiInit = FALSE; BOOL fLinProcInit =FALSE; atomic_set(&AtomicShutdown_g, TRUE); // open character device from debugfs to disable tracing when necessary hAppFdTracingEnabled_g = open("/sys/kernel/debug/tracing/tracing_enabled", O_WRONLY, 0666); // get node ID from insmod command line EplApiInitParam.m_uiNodeId = uiNodeId_g; if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) { // invalid node ID set // set default node ID EplApiInitParam.m_uiNodeId = NODEID; } uiNodeId_g = EplApiInitParam.m_uiNodeId; // calculate IP address EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId; EplApiInitParam.m_fAsyncOnly = FALSE; EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam); EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress)); EplApiInitParam.m_dwFeatureFlags = (DWORD) ~0UL; EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const EplApiInitParam.m_dwPresMaxLatency = 50000; // const; only required for IdentRes EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes) EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes) EplApiInitParam.m_dwAsndMaxLatency = 150000; // const; only required for IdentRes EplApiInitParam.m_uiMultiplCycleCnt = 0; // required for error detection EplApiInitParam.m_uiAsyncMtu = 1500; // required to set up max frame size EplApiInitParam.m_uiPrescaler = 2; // required for sync EplApiInitParam.m_dwLossOfFrameTolerance = 500000; EplApiInitParam.m_dwAsyncSlotTimeout = 3000000; EplApiInitParam.m_dwWaitSocPreq = 150000; EplApiInitParam.m_dwDeviceType = (DWORD) ~0UL; // NMT_DeviceType_U32 EplApiInitParam.m_dwVendorId = (DWORD) ~0UL; // NMT_IdentityObject_REC.VendorId_U32 EplApiInitParam.m_dwProductCode = (DWORD) ~0UL; // NMT_IdentityObject_REC.ProductCode_U32 EplApiInitParam.m_dwRevisionNumber = (DWORD) ~0UL; // NMT_IdentityObject_REC.RevisionNo_U32 EplApiInitParam.m_dwSerialNumber = (DWORD) ~0UL; // NMT_IdentityObject_REC.SerialNo_U32 EplApiInitParam.m_dwSubnetMask = SUBNET_MASK; EplApiInitParam.m_dwDefaultGateway = 0; EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname)); EplApiInitParam.m_uiSyncNodeId = EPL_C_ADR_SYNC_ON_SOA; EplApiInitParam.m_fSyncOnPrcNode = FALSE; // set callback functions EplApiInitParam.m_pfnCbEvent = AppCbEvent; EplApiInitParam.m_pfnCbSync = AppCbSync; EplApiInitParam.m_pfnObdInitRam = EplObdInitRam; printk("\n\n Hello, I'm a simple POWERLINK node running as %s!\n (build: %s / %s)\n\n", (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"), __DATE__, __TIME__); // initialize the Linux a wait queue for shutdown of this module init_waitqueue_head(&WaitQueueShutdown_g); // initialize the procfs device EplRet = EplLinProcInit(); if (EplRet != kEplSuccessful) { PRINTF("EplLinProcInit failed!\n"); goto Exit; } fLinProcInit = TRUE; // initialize POWERLINK stack EplRet = EplApiInitialize(&EplApiInitParam); if(EplRet != kEplSuccessful) { PRINTF("EplApiInitialize failed!\n"); goto Exit; } fApiInit = TRUE; EplRet = EplApiSetCdcFilename(pszCdcFilename_g); if(EplRet != kEplSuccessful) { goto Exit; } PRINTF("Initializing process image...\n"); PRINTF("Size of input process image: %ld\n", sizeof(AppProcessImageIn_g)); PRINTF("Size of output process image: %ld\n", sizeof (AppProcessImageOut_g)); AppProcessImageCopyJob_g.m_fNonBlocking = FALSE; AppProcessImageCopyJob_g.m_uiPriority = 0; AppProcessImageCopyJob_g.m_In.m_pPart = &AppProcessImageIn_g; AppProcessImageCopyJob_g.m_In.m_uiOffset = 0; AppProcessImageCopyJob_g.m_In.m_uiSize = sizeof (AppProcessImageIn_g); AppProcessImageCopyJob_g.m_Out.m_pPart = &AppProcessImageOut_g; AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0; AppProcessImageCopyJob_g.m_Out.m_uiSize = sizeof (AppProcessImageOut_g); EplRet = EplApiProcessImageAlloc(sizeof (AppProcessImageIn_g), sizeof (AppProcessImageOut_g), 2, 2); if (EplRet != kEplSuccessful) { goto Exit; } EplRet = EplApiProcessImageSetup(); if (EplRet != kEplSuccessful) { goto Exit; } // start the NMT state machine EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset); atomic_set(&AtomicShutdown_g, FALSE); Exit: PRINTF("EplLinInit(): returns 0x%X\n", EplRet); if (EplRet != kEplSuccessful) { if (fApiInit != FALSE) { EplApiShutdown(); } if (fLinProcInit != FALSE) { EplLinProcFree(); } return -ENODEV; } else { return 0; } }