//--------------------------------------------------------------------------- // // Function: EplLinExit // // Description: Exit point of kernel module //// // // Parameters: N/A // // // Returns: Return code // //--------------------------------------------------------------------------- static void __exit EplLinExit (void) { tEplKernel EplRet; // halt the NMT state machine // so the processing of POWERLINK frames stops EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); // wait until NMT state machine is shut down wait_event_interruptible(WaitQueueShutdown_g, (atomic_read(&AtomicShutdown_g) == TRUE)); /* if ((iErr != 0) || (atomic_read(&AtomicShutdown_g) == EVENT_STATE_IOCTL)) { // waiting was interrupted by signal or application called wrong function EplRet = kEplShutdown; }*/ // Free resources used by the process image API EplRet = EplApiProcessImageFree(); // delete instance for all modules EplRet = EplApiShutdown(); PRINTF("EplApiShutdown(): 0x%X\n", EplRet); // deinitialize proc fs EplRet = EplLinProcFree(); PRINTF("EplLinProcFree(): 0x%X\n", EplRet); if (IS_FD_VALID(hAppFdTracingEnabled_g)) { close(hAppFdTracingEnabled_g); } }
static void __exit EplLinExit(void) { tEplKernel EplRet; // delete instance for all modules // EplRet = EplApiShutdown(); // printk("EplApiShutdown(): 0x%X\n", EplRet); // deinitialize proc fs EplRet = EplLinProcFree(); printk("EplLinProcFree(): 0x%X\n", EplRet); TRACE0("EPL: + EplLinExit...\n"); // remove cdev structure cdev_del(pEpl_cdev_g); // unregister character device handler unregister_chrdev_region(nDevNum_g, 1); TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME); TRACE0("EPL: - EplLinExit\n"); }
static void __exit EplLinExit (void) { tEplKernel EplRet; TRACE0("EPL: + EplLinExit...\n"); // deinitialize proc fs EplRet = EplLinProcFree(); TRACE1("EplLinProcFree(): 0x%X\n", EplRet); // deregister misc device misc_deregister(&EplLinMiscDevice_g); TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME); TRACE0("EPL: - EplLinExit\n"); }
static void __exit EplLinExit(void) { tEplKernel EplRet; // delete instance for all modules // EplRet = EplApiShutdown(); // printk("EplApiShutdown(): 0x%X\n", EplRet); // deinitialize proc fs EplRet = EplLinProcFree(); printk("EplLinProcFree(): 0x%X\n", EplRet); TRACE0("EPL: + EplLinExit...\n"); #ifdef CONFIG_DEVFS_FS // remove device node from DEVFS devfs_remove(EPLLIN_DEV_NAME); TRACE1("EPL: Device node '/dev/%s' removed.\n", EPLLIN_DEV_NAME); // unregister character device handler unregister_chrdev(nDrvMajorNumber_g, EPLLIN_DRV_NAME); #else // remove cdev structure cdev_del(pEpl_cdev_g); // unregister character device handler unregister_chrdev_region(nDevNum_g, 1); #endif TRACE1("EPL: Driver '%s' removed.\n", EPLLIN_DRV_NAME); TRACE0("EPL: - EplLinExit\n"); }
//--------------------------------------------------------------------------- // // 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; } }