📄 rt_linux.c
字号:
NDIS_STATUS RtmpOSTaskKill( IN RTMP_OS_TASK *pTask){ RTMP_ADAPTER *pAd; int ret = NDIS_STATUS_FAILURE; pAd = (RTMP_ADAPTER *)pTask->priv;#ifdef KTHREAD_SUPPORT if (pTask->kthread_task) { kthread_stop(pTask->kthread_task); ret = NDIS_STATUS_SUCCESS; }#else CHECK_PID_LEGALITY(pTask->taskPID) { printk("Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID)); mb(); pTask->task_killed = 1; mb(); ret = KILL_THREAD_PID(pTask->taskPID, SIGTERM, 1); if (ret) { printk(KERN_WARNING "kill task(%s) with pid(%d) failed(retVal=%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID), ret); } else { wait_for_completion(&pTask->taskComplete); pTask->taskPID = THREAD_PID_INIT_VALUE; pTask->task_killed = 0; ret = NDIS_STATUS_SUCCESS; } }#endif return ret; }INT RtmpOSTaskNotifyToExit( IN RTMP_OS_TASK *pTask){#ifndef KTHREAD_SUPPORT complete_and_exit(&pTask->taskComplete, 0);#endif return 0;}void RtmpOSTaskCustomize( IN RTMP_OS_TASK *pTask){#ifndef KTHREAD_SUPPORT#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) daemonize((PSTRING)&pTask->taskName[0]/*"%s",pAd->net_dev->name*/); allow_signal(SIGTERM); allow_signal(SIGKILL); current->flags |= PF_NOFREEZE;#else unsigned long flags; daemonize(); reparent_to_init(); strcpy(current->comm, &pTask->taskName[0]); siginitsetinv(¤t->blocked, sigmask(SIGTERM) | sigmask(SIGKILL)); /* Allow interception of SIGKILL only * Don't allow other signals to interrupt the transmission */#if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) spin_lock_irqsave(¤t->sigmask_lock, flags); flush_signals(current); recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags);#endif#endif /* signal that we've started the thread */ complete(&pTask->taskComplete);#endif}NDIS_STATUS RtmpOSTaskAttach( IN RTMP_OS_TASK *pTask, IN int (*fn)(void *), IN void *arg){ NDIS_STATUS status = NDIS_STATUS_SUCCESS; pid_t pid_number = -1; #ifdef KTHREAD_SUPPORT pTask->task_killed = 0; pTask->kthread_task = NULL; pTask->kthread_task = kthread_run(fn, arg, pTask->taskName); if (IS_ERR(pTask->kthread_task)) status = NDIS_STATUS_FAILURE;#else pid_number = kernel_thread(fn, arg, RTMP_OS_MGMT_TASK_FLAGS); if (pid_number < 0) { DBGPRINT (RT_DEBUG_ERROR, ("Attach task(%s) failed!\n", pTask->taskName)); status = NDIS_STATUS_FAILURE; } else { pTask->taskPID = GET_PID(pid_number); // Wait for the thread to start wait_for_completion(&pTask->taskComplete); status = NDIS_STATUS_SUCCESS; }#endif return status;}NDIS_STATUS RtmpOSTaskInit( IN RTMP_OS_TASK *pTask, IN PSTRING pTaskName, IN VOID *pPriv){ int len; ASSERT(pTask);#ifndef KTHREAD_SUPPORT NdisZeroMemory((PUCHAR)(pTask), sizeof(RTMP_OS_TASK));#endif len = strlen(pTaskName); len = len > (RTMP_OS_TASK_NAME_LEN -1) ? (RTMP_OS_TASK_NAME_LEN-1) : len; NdisMoveMemory(&pTask->taskName[0], pTaskName, len); pTask->priv = pPriv;#ifndef KTHREAD_SUPPORT RTMP_SEM_EVENT_INIT_LOCKED(&(pTask->taskSema)); pTask->taskPID = THREAD_PID_INIT_VALUE; init_completion (&pTask->taskComplete);#endif return NDIS_STATUS_SUCCESS;}void RTMP_IndicateMediaState( IN PRTMP_ADAPTER pAd){ if (pAd->CommonCfg.bWirelessEvent) { if (pAd->IndicateMediaState == NdisMediaStateConnected) { RTMPSendWirelessEvent(pAd, IW_STA_LINKUP_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); } else { RTMPSendWirelessEvent(pAd, IW_STA_LINKDOWN_EVENT_FLAG, pAd->MacTab.Content[BSSID_WCID].Addr, BSS0, 0); } }}#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1//static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) //samplestruct net_device *alloc_netdev( int sizeof_priv, const char *mask, void (*setup)(struct net_device *)){ struct net_device *dev; INT alloc_size; /* ensure 32-byte alignment of the private area */ alloc_size = sizeof (*dev) + sizeof_priv + 31; dev = (struct net_device *) kmalloc(alloc_size, GFP_KERNEL); if (dev == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("alloc_netdev: Unable to allocate device memory.\n")); return NULL; } memset(dev, 0, alloc_size); if (sizeof_priv) dev->priv = (void *) (((long)(dev + 1) + 31) & ~31); setup(dev); strcpy(dev->name, mask); return dev;}#endif // LINUX_VERSION_CODE //int RtmpOSWrielessEventSend( IN RTMP_ADAPTER *pAd, IN UINT32 eventType, IN INT flags, IN PUCHAR pSrcMac, IN PUCHAR pData, IN UINT32 dataLen){ union iwreq_data wrqu; memset(&wrqu, 0, sizeof(wrqu)); if (flags) wrqu.data.flags = flags; if (pSrcMac) memcpy(wrqu.ap_addr.sa_data, pSrcMac, MAC_ADDR_LEN); if ((pData!= NULL) && (dataLen > 0)) wrqu.data.length = dataLen; wireless_send_event(pAd->net_dev, eventType, &wrqu, (char *)pData); return 0;}int RtmpOSNetDevAddrSet( IN PNET_DEV pNetDev, IN PUCHAR pMacAddr){ struct net_device *net_dev; RTMP_ADAPTER *pAd; net_dev = pNetDev; pAd = (RTMP_ADAPTER *)net_dev->priv; #ifdef CONFIG_STA_SUPPORT // work-around for the SuSE due to it has it's own interface name management system. IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { NdisZeroMemory(pAd->StaCfg.dev_name, 16); NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, strlen(net_dev->name)); }#endif // CONFIG_STA_SUPPORT // NdisMoveMemory(net_dev->dev_addr, pMacAddr, 6); return 0;}/* * Assign the network dev name for created Ralink WiFi interface. */static int RtmpOSNetDevRequestName( IN RTMP_ADAPTER *pAd, IN PNET_DEV dev, IN PSTRING pPrefixStr, IN INT devIdx){ PNET_DEV existNetDev; STRING suffixName[IFNAMSIZ]; STRING desiredName[IFNAMSIZ]; int ifNameIdx, prefixLen, slotNameLen; int Status; prefixLen = strlen(pPrefixStr); ASSERT((prefixLen < IFNAMSIZ)); for (ifNameIdx = devIdx; ifNameIdx < 32; ifNameIdx++) { memset(suffixName, 0, IFNAMSIZ); memset(desiredName, 0, IFNAMSIZ); strncpy(&desiredName[0], pPrefixStr, prefixLen); #ifdef MULTIPLE_CARD_SUPPORT if (pAd->MC_RowID >= 0) sprintf(suffixName, "%02d_%d", pAd->MC_RowID, ifNameIdx); else#endif // MULTIPLE_CARD_SUPPORT // sprintf(suffixName, "%d", ifNameIdx); slotNameLen = strlen(suffixName); ASSERT(((slotNameLen + prefixLen) < IFNAMSIZ)); strcat(desiredName, suffixName); existNetDev = RtmpOSNetDevGetByName(dev, &desiredName[0]); if (existNetDev == NULL) break; else RtmpOSNetDeviceRefPut(existNetDev); } if(ifNameIdx < 32) { strcpy(&dev->name[0], &desiredName[0]); Status = NDIS_STATUS_SUCCESS; } else { DBGPRINT(RT_DEBUG_ERROR, ("Cannot request DevName with preifx(%s) and in range(0~32) as suffix from OS!\n", pPrefixStr)); Status = NDIS_STATUS_FAILURE; } return Status;}void RtmpOSNetDevClose( IN PNET_DEV pNetDev){ dev_close(pNetDev);}void RtmpOSNetDevFree(PNET_DEV pNetDev){ ASSERT(pNetDev); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) free_netdev(pNetDev);#else kfree(pNetDev);#endif}INT RtmpOSNetDevAlloc( IN PNET_DEV *new_dev_p, IN UINT32 privDataSize){ // assign it as null first. *new_dev_p = NULL; DBGPRINT(RT_DEBUG_TRACE, ("Allocate a net device with private data size=%d!\n", privDataSize));#if LINUX_VERSION_CODE <= 0x20402 // Red Hat 7.1 *new_dev_p = alloc_netdev(privDataSize, "eth%d", ether_setup);#else *new_dev_p = alloc_etherdev(privDataSize);#endif // LINUX_VERSION_CODE // if (*new_dev_p) return NDIS_STATUS_SUCCESS; else return NDIS_STATUS_FAILURE;}PNET_DEV RtmpOSNetDevGetByName(PNET_DEV pNetDev, PSTRING pDevName){ PNET_DEV pTargetNetDev = NULL;#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26) pTargetNetDev = dev_get_by_name(dev_net(pNetDev), pDevName);#else ASSERT(pNetDev); pTargetNetDev = dev_get_by_name(pNetDev->nd_net, pDevName);#endif#else pTargetNetDev = dev_get_by_name(pDevName);#endif // KERNEL_VERSION(2,6,24) //#else int devNameLen; devNameLen = strlen(pDevName); ASSERT((devNameLen <= IFNAMSIZ)); for(pTargetNetDev=dev_base; pTargetNetDev!=NULL; pTargetNetDev=pTargetNetDev->next) { if (strncmp(pTargetNetDev->name, pDevName, devNameLen) == 0) break; }#endif // KERNEL_VERSION(2,5,0) // return pTargetNetDev;}void RtmpOSNetDeviceRefPut(PNET_DEV pNetDev){#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* every time dev_get_by_name is called, and it has returned a valid struct net_device*, dev_put should be called afterwards, because otherwise the machine hangs when the device is unregistered (since dev->refcnt > 1). */ if(pNetDev) dev_put(pNetDev);#endif // LINUX_VERSION_CODE //}INT RtmpOSNetDevDestory( IN RTMP_ADAPTER *pAd, IN PNET_DEV pNetDev){ // TODO: Need to fix this printk("WARNING: This function(%s) not implement yet!!!\n", __FUNCTION__); return 0;}void RtmpOSNetDevDetach(PNET_DEV pNetDev){ unregister_netdev(pNetDev);}int RtmpOSNetDevAttach( IN PNET_DEV pNetDev, IN RTMP_OS_NETDEV_OP_HOOK *pDevOpHook){ int ret, rtnl_locked = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n")); // If we need hook some callback function to the net device structrue, now do it. if (pDevOpHook) { PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pNetDev->priv; pNetDev->open = pDevOpHook->open; pNetDev->stop = pDevOpHook->stop; pNetDev->hard_start_xmit = (HARD_START_XMIT_FUNC)(pDevOpHook->xmit); pNetDev->do_ioctl = pDevOpHook->ioctl; /* if you don't implement get_stats, just leave the callback function as NULL, a dummy function will make kernel panic. */ if (pDevOpHook->get_stats) pNetDev->get_stats = pDevOpHook->get_stats; /* OS specific flags, here we used to indicate if we are virtual interface */ pNetDev->priv_flags = pDevOpHook->priv_flags; #if (WIRELESS_EXT < 21) && (WIRELESS_EXT >= 12) pNetDev->get_wireless_stats = rt28xx_get_wireless_stats;#endif#ifdef CONFIG_STA_SUPPORT#if WIRELESS_EXT >= 12 if (pAd->OpMode == OPMODE_STA) { pNetDev->wireless_handlers = &rt28xx_iw_handler_def; }#endif //WIRELESS_EXT >= 12#endif // CONFIG_STA_SUPPORT //#ifdef CONFIG_APSTA_MIXED_SUPPORT#if WIRELESS_EXT >= 12 if (pAd->OpMode == OPMODE_AP) { pNetDev->wireless_handlers = &rt28xx_ap_iw_handler_def; }#endif //WIRELESS_EXT >= 12#endif // CONFIG_APSTA_MIXED_SUPPORT // // copy the net device mac address to the net_device structure. NdisMoveMemory(pNetDev->dev_addr, &pDevOpHook->devAddr[0], MAC_ADDR_LEN); rtnl_locked = pDevOpHook->needProtcted; }#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) pNetDev->validate_addr = NULL;#endif if (rtnl_locked) ret = register_netdevice(pNetDev); else ret = register_netdev(pNetDev); DBGPRINT(RT_DEBUG_TRACE, ("<---RtmpOSNetDevAttach(), ret=%d\n", ret)); if (ret == 0) return NDIS_STATUS_SUCCESS; else return NDIS_STATUS_FAILURE;}PNET_DEV RtmpOSNetDevCreate( IN RTMP_ADAPTER *pAd, IN INT devType, IN INT devNum, IN INT privMemSize, IN PSTRING pNamePrefix){ struct net_device *pNetDev = NULL; int status; /* allocate a new network device */ status = RtmpOSNetDevAlloc(&pNetDev, 0 /*privMemSize*/); if (status != NDIS_STATUS_SUCCESS) { /* allocation fail, exit */ DBGPRINT(RT_DEBUG_ERROR, ("Allocate network device fail (%s)...\n", pNamePrefix)); return NULL; } /* find a available interface name, max 32 interfaces */ status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum); if (status != NDIS_STATUS_SUCCESS) { /* error! no any available ra name can be used! */ DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix)); RtmpOSNetDevFree(pNetDev); return NULL; } else { DBGPRINT(RT_DEBUG_TRACE, ("The name of the new %s interface is %s...\n", pNamePrefix, pNetDev->name)); } return pNetDev;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -