📄 rtusb_main.c
字号:
DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCmdThread\n");#else DBGPRINT(RT_DEBUG_TRACE, "RTUSBCmdThread end\n"); pAdapter->RTUSBCmdThr_active = 0;#endif return 0;}static void *usb_rtusb_probe(struct usb_device *dev, UINT interface, const struct usb_device_id *id_table){ PRT2570ADAPTER pAdapter = (PRT2570ADAPTER)NULL; int i; struct net_device *netdev; int res = -ENOMEM; for (i = 0; i < rtusb_usb_id_len; i++) { if (le16_to_cpu(dev->descriptor.idVendor) == rtusb_usb_id[i].idVendor && le16_to_cpu(dev->descriptor.idProduct) == rtusb_usb_id[i].idProduct) { printk("idVendor = 0x%x, idProduct = 0x%x \n", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); break; } } if (i == rtusb_usb_id_len) { printk("Device Descriptor not matching\n"); return NULL; } netdev = alloc_etherdev(sizeof (*pAdapter)); if(!netdev) { //if (!(pAdapter->net = init_etherdev(0, 0) )) { printk("alloc_etherdev failed\n"); MOD_DEC_USE_COUNT; usb_dec_dev_use(dev); return NULL; } pAdapter = netdev->priv; pAdapter->net = netdev; netif_stop_queue(netdev); pAdapter->config = dev->config; pAdapter->usb = dev; SET_MODULE_OWNER(pAdapter->net); ether_setup(pAdapter->net);#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) SET_ETHTOOL_OPS(net_dev, &rt2x00_ethtool_ops);#endif netdev->open = usb_rtusb_open; netdev->hard_start_xmit = RTUSBSendPackets; netdev->stop = usb_rtusb_close; netdev->priv = pAdapter; netdev->get_stats = rt_getstats;#if WIRELESS_EXT >= 11 netdev->get_wireless_stats = RTUSB_get_wireless_stats; netdev->wireless_handlers = (struct iw_handler_def *) &rt2500usb_iw_handler_def;#endif netdev->set_mac_address = rt2570_set_mac_address; netdev->do_ioctl = usb_rt2570_ioctl; pAdapter->net->hard_header_len = 14; pAdapter->net->mtu = 1500; pAdapter->net->addr_len = 6; pAdapter->net->weight = 64; pAdapter->MediaState = NdisMediaStateDisconnected; {// find available int i=0; char slot_name[IFNAMSIZ]; struct net_device *device; for (i = 0; i < 8; i++) { sprintf(slot_name, "rausb%d", i); for (device = dev_base; device != NULL; device = device->next) { if (strncmp(device->name, slot_name, 6) == 0) { break; } } if(device == NULL) break; } if(i == 8) { DBGPRINT(RT_DEBUG_ERROR, "No available slot name\n"); return NULL; } sprintf(pAdapter->net->name, "rausb%d", i); DBGPRINT(RT_DEBUG_ERROR, "usbdevice->name %s\n",pAdapter->net->name); } //pAdapter->rx_bh.data = (unsigned long)pAdapter; pAdapter->rx_bh.func = RTUSBRxPacket; res = register_netdev(pAdapter->net); if (res) goto out3; // start as if the link is up // netif_device_attach (pAdapter->net); PortCfgInit(pAdapter); return pAdapter;out3: printk("3 register_netdev failed err=%d\n",res); return NULL;}//Disconnect function is called within exit routinestatic void usb_rtusb_disconnect(struct usb_device *dev, void *ptr){ PRT2570ADAPTER pAdapter = (PRT2570ADAPTER) ptr; if (!pAdapter) return; tasklet_kill(&pAdapter->rx_bh); RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); // for debug, wait to show some messages to /proc system udelay(1); //After Add Thread implementation, Upon exec there, pAdapter->net seems becomes NULL, //need to check why??? //assert(pAdapter->net != NULL) if(pAdapter->net != NULL) { printk("unregister_netdev( )\n"); unregister_netdev (pAdapter->net); } DBGPRINT(RT_DEBUG_ERROR,"<=== RTUSB disconnect successfully\n");}#elsestatic int usb_rtusb_close(struct net_device *net){ PRT2570ADAPTER pAdapter = (PRT2570ADAPTER) net->priv; int ret; DECLARE_WAIT_QUEUE_HEAD (unlink_wakeup); DECLARE_WAITQUEUE (wait, current); int i = 0; netif_carrier_off(pAdapter->net); netif_stop_queue(pAdapter->net); // ensure there are no more active urbs. add_wait_queue (&unlink_wakeup, &wait); pAdapter->wait = &unlink_wakeup; // maybe wait for deletions to finish. while ((i < 25) && atomic_read(&pAdapter->PendingRx) > 0) {#if LINUX_VERSION_CODE >KERNEL_VERSION(2,6,9) msleep(UNLINK_TIMEOUT_MS);#endif i++; } pAdapter->wait = NULL; remove_wait_queue (&unlink_wakeup, &wait); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) if (pAdapter->MLMEThr_pid >= 0) { mlme_kill = 1; RTUSBCMDUp(pAdapter, (&(pAdapter->mlme_semaphore))); wmb(); // need to check ret = kill_proc (pAdapter->MLMEThr_pid, SIGTERM, 1); if (ret) { printk (KERN_ERR "%s: unable to signal thread\n", pAdapter->net->name); return ret; } wait_for_completion (&pAdapter->notify); } if (pAdapter->RTUSBCmdThr_pid>= 0) { RTUSBCmd_kill = 1; RTUSBCMDUp(pAdapter, (&(pAdapter->RTUSBCmd_semaphore))); wmb(); // need to check ret = kill_proc (pAdapter->RTUSBCmdThr_pid, SIGTERM, 1); if (ret) { printk (KERN_ERR "%s: unable to signal thread\n", pAdapter->net->name); return ret; } wait_for_completion (&pAdapter->notify); }#else if (pAdapter->MLMEThr_active) { ret = kthread_stop(pAdapter->MLMEThr); if (ret) { printk (KERN_ERR "%s: unable to stop thread\n", pAdapter->net->name); return ret; } } if (pAdapter->RTUSBCmdThr_active) { ret = kthread_stop(pAdapter->RTUSBCmdThr); if (ret) { printk (KERN_ERR "%s: unable to stop thread\n", pAdapter->net->name); return ret; } }#endif RTUSBHalt( pAdapter, FALSE); DBGPRINT(RT_DEBUG_TEMP,"<--usb_rt2570_close\n"); module_put(THIS_MODULE); return 0;}int MlmeThread(void * Context){ PRT2570ADAPTER pAdapter = (PRT2570ADAPTER)Context;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) daemonize("rt2500usb"); allow_signal(SIGTERM); current->flags |= PF_NOFREEZE; /* signal that we've started the thread */ complete(&(pAdapter->notify));#else pAdapter->MLMEThr_active = 1;#endif while (1) {#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) if (kthread_should_stop()) break;#endif /* lock the device pointers */ down(&(pAdapter->mlme_semaphore));#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) if (mlme_kill) break;#endif /* lock the device pointers , need to check if required*/ down(&(pAdapter->usbdev_semaphore)); MlmeHandler(pAdapter); /* unlock the device pointers */ up(&(pAdapter->usbdev_semaphore)); }#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) complete_and_exit (&pAdapter->notify, 0); DBGPRINT(RT_DEBUG_TRACE, "<---MlmeThread\n");#else DBGPRINT(RT_DEBUG_TRACE, "MlmeThread end\n"); pAdapter->MLMEThr_active = 0;#endif return 0;}int RTUSBCmdThread(void * Context){ PRT2570ADAPTER pAdapter = (PRT2570ADAPTER)Context;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) daemonize("rt2500usb"); allow_signal(SIGTERM); current->flags |= PF_NOFREEZE; /* signal that we've started the thread */ complete(&(pAdapter->notify));#else pAdapter->RTUSBCmdThr_active = 1;#endif while (1) {#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0) if (kthread_should_stop()) break;#endif /* lock the device pointers */ down(&(pAdapter->RTUSBCmd_semaphore));#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) if (RTUSBCmd_kill) break;#endif /* lock the device pointers , need to check if required*/ down(&(pAdapter->usbdev_semaphore)); CMDHandler(pAdapter); /* unlock the device pointers */ up(&(pAdapter->usbdev_semaphore)); }#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) complete_and_exit (&pAdapter->notify, 0); DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCmdThread\n");#else DBGPRINT(RT_DEBUG_TRACE, "RTUSBCmdThread end\n"); pAdapter->RTUSBCmdThr_active = 0;#endif return 0;}static int usb_rtusb_probe (struct usb_interface *intf, const struct usb_device_id *id){ struct usb_device *dev = interface_to_usbdev(intf); PRT2570ADAPTER pAdapter = (PRT2570ADAPTER)NULL; int i; struct net_device *netdev; int res = -ENOMEM; usb_get_dev(dev); for (i = 0; i < rtusb_usb_id_len; i++) { if (le16_to_cpu(dev->descriptor.idVendor) == rtusb_usb_id[i].idVendor && le16_to_cpu(dev->descriptor.idProduct) == rtusb_usb_id[i].idProduct) { printk("idVendor = 0x%x, idProduct = 0x%x \n", le16_to_cpu(dev->descriptor.idVendor), le16_to_cpu(dev->descriptor.idProduct)); break; } } if (i == rtusb_usb_id_len) { printk("Device Descriptor not matching\n"); return res; } netdev = alloc_etherdev(sizeof (*pAdapter)); if(!netdev) { //if (!(pAdapter->net = init_etherdev(0, 0) )) { printk("alloc_etherdev failed\n"); module_put(THIS_MODULE); return res; } pAdapter = netdev->priv; pAdapter->net = netdev; netif_stop_queue(netdev); pAdapter->config = &dev->config->desc; pAdapter->usb = dev; SET_MODULE_OWNER(pAdapter->net); ether_setup(pAdapter->net);#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0) SET_ETHTOOL_OPS(pAdapter->net, &rt2x00_ethtool_ops);#endif netdev->open = usb_rtusb_open; netdev->stop = usb_rtusb_close; netdev->priv = pAdapter; netdev->hard_start_xmit = RTUSBSendPackets; netdev->get_stats = rt_getstats;#if 1#if WIRELESS_EXT >= 12#if WIRELESS_EXT < 17 netdev->get_wireless_stats = RTUSB_get_wireless_stats;#else netdev->wireless_handlers = (struct iw_handler_def *) &rt2500usb_iw_handler_def;#endif#endif netdev->do_ioctl = usb_rt2570_ioctl;#endif pAdapter->net->set_mac_address = rt2570_set_mac_address; pAdapter->net->hard_header_len = 14; pAdapter->net->mtu = 1500; pAdapter->net->addr_len = 6; pAdapter->net->weight = 64; pAdapter->MediaState = NdisMediaStateDisconnected;#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) pAdapter->MLMEThr_pid= -1; pAdapter->RTUSBCmdThr_pid= -1;#else pAdapter->MLMEThr_active = 0; pAdapter->RTUSBCmdThr_active = 0;#endif RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_RESET_IN_PROGRESS); SET_NETDEV_DEV(pAdapter->net, &intf->dev); {// find available int i=0; char slot_name[IFNAMSIZ]; struct net_device *device; for (i = 0; i < 8; i++) { sprintf(slot_name, "rausb%d", i); for (device = dev_base; device != NULL; device = device->next) { if (strncmp(device->name, slot_name, 6) == 0) { break; } } if(device == NULL) break; } if(i == 8) { DBGPRINT(RT_DEBUG_ERROR, "No available slot name\n"); return res; } sprintf(pAdapter->net->name, "rausb%d", i); } pAdapter->rx_bh.func = RTUSBRxPacket; //bottom half data is assign at each task_scheduler //pAdapter->rx_bh.data = (unsigned long)pAdapter; res = register_netdev(pAdapter->net); if (res) goto out3; usb_set_intfdata(intf, pAdapter); PortCfgInit(pAdapter); return 0;out3: printk("3 register_netdev failed err=%d\n",res); free_netdev(netdev); return -1;}static void usb_rtusb_disconnect(struct usb_interface *intf){ struct usb_device *dev = interface_to_usbdev(intf); PRT2570ADAPTER pAdapter = (PRT2570ADAPTER)NULL; pAdapter = usb_get_intfdata(intf); usb_set_intfdata(intf, NULL); RTMP_SET_FLAG(pAdapter, fRTMP_ADAPTER_REMOVE_IN_PROGRESS); DBGPRINT(RT_DEBUG_ERROR,"unregister usbnet usb-%s-%s\n", dev->bus->bus_name, dev->devpath); if (!pAdapter) return; tasklet_kill(&pAdapter->rx_bh); // for debug, wait to show some messages to /proc system udelay(1); //After Add Thread implementation, Upon exec there, pAdapter->net seems becomes NULL, //need to check why??? //assert(pAdapter->net != NULL) if(pAdapter->net != NULL) { printk("unregister_netdev( )\n"); unregister_netdev (pAdapter->net); } udelay(1); flush_scheduled_work (); udelay(1); free_netdev(pAdapter->net); usb_put_dev(dev); udelay(1); DBGPRINT(RT_DEBUG_ERROR,"<=== RTUSB disconnect successfully\n");}#endif int __init usb_rtusb_init(void){ DBGPRINT(RT_DEBUG_ERROR,"enter rtusb init( )\n"); return usb_register(&rtusb_driver);} void __exit usb_rtusb_exit(void){ udelay(1); udelay(1); usb_deregister(&rtusb_driver); printk("<===usb_rtusb_exit\n");}/**************************************************************/MODULE_DESCRIPTION("Ralink RT2570 usb 802.11g WLAN driver " DRV_VERSION " " DRV_RELDATE);MODULE_AUTHOR("http://rt2x00.sourceforge.net");MODULE_DEVICE_TABLE(usb, rtusb_usb_id);MODULE_LICENSE("GPL");module_init(usb_rtusb_init); // initialization functionmodule_exit(usb_rtusb_exit); // exit function/**************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -