📄 rtmp_main.c
字号:
if (i == rtusb_usb_id_len) { KPRINT(KERN_CRIT, "Device Descriptor not matching\n"); goto out_noalloc; } /* RTMP_ADAPTER is too big with 64-bit pointers, and using the builtin net_device private area causes the allocation to exceed 128KB and fail. So we allocate it separately. */ pAd = kzalloc(sizeof (*pAd), GFP_KERNEL); if (!pAd) { KPRINT(KERN_CRIT, "couldn't allocate RTMP_ADAPTER\n"); goto out_noalloc; } netdev = alloc_etherdev(0); if (!netdev) { KPRINT(KERN_CRIT, "alloc_etherdev failed\n"); goto out_nonetdev; } netdev->priv = pAd; pAd->net_dev = netdev; netif_stop_queue(netdev); pAd->config = dev->config; pAd->pUsb_Dev= dev; SET_MODULE_OWNER(netdev); ether_setup(netdev); netdev->open = usb_rtusb_open; netdev->hard_start_xmit = RTMPSendPackets; netdev->stop = usb_rtusb_close; netdev->get_stats = rt73_get_ether_stats;#if WIRELESS_EXT >= 12#if WIRELESS_EXT < 17 netdev->get_wireless_stats = rt73_get_wireless_stats;#endif netdev->wireless_handlers = (struct iw_handler_def *) &rt73_iw_handler_def;#endif netdev->do_ioctl = rt73_ioctl; netdev->hard_header_len = 14; netdev->mtu = 1500; netdev->addr_len = 6;#if WIRELESS_EXT >= 15 netdev->weight = 64;#endif OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->MLMEThr_pid= -1; pAd->RTUSBCmdThr_pid= -1; SET_NETDEV_DEV(netdev, &intf->dev); {// find available int i=0; char slot_name[IFNAMSIZ]; struct net_device *device; struct usb_interface *ifp= &dev->actconfig->interface[interface]; // get interface from system struct usb_interface_descriptor *as; struct usb_endpoint_descriptor *ep; if (ifname == NULL) strcpy(netdev->name, "wlan%d"); else strncpy(netdev->name, ifname, IFNAMSIZ); for (i = 0; i < 8; i++) { sprintf(slot_name, netdev->name, i); read_lock_bh(&dev_base_lock); // avoid multiple init for (device = first_net_device(); device != NULL; device = next_net_device(device)) { if (strncmp(device->name, slot_name, IFNAMSIZ) == 0) { break; } } read_unlock_bh(&dev_base_lock); if(device == NULL) break; } if(i == 8) { DBGPRINT(RT_DEBUG_ERROR, "No available slot name\n"); KPRINT(KERN_CRIT, "No available slot name\n"); goto out; } sprintf(netdev->name, slot_name, i); DBGPRINT(RT_DEBUG_INFO, "usb device name %s\n",netdev->name); /* get Max Packet Size from usb_dev endpoint */// ifp = dev->actconfig->interface + i; as = ifp->altsetting + ifp->act_altsetting; ep = as->endpoint; pAd->BulkOutMaxPacketSize = le16_to_cpu(ep[i].wMaxPacketSize); // Workaround for EDIMAX 7318USg suggested by Ivo in forum if (pAd->BulkOutMaxPacketSize == 0) { pAd->BulkOutMaxPacketSize = 1; DBGPRINT(RT_DEBUG_WARN, "- %s: Device reports zero length wMaxPacketSize. " "Using workaround.\n", __FUNCTION__); KPRINT(KERN_WARNING, "Device reports zero length wMaxPacketSize. " "Using workaround.\n"); } DBGPRINT(RT_DEBUG_INFO, "BulkOutMaxPacketSize %d\n", pAd->BulkOutMaxPacketSize); } res = register_netdev(netdev); if (res) { KPRINT(KERN_CRIT, "register_netdev failed err=%d\n",res); goto out; } res = common_probe(pAd); if (res) goto out;#ifdef CONFIG_PM /* register power management */ pAd->pmdev = pm_register(PM_USB_DEV, 0, rt73_pm_callback); if (pAd->pmdev) { pAd->pmdev->data = pAd; }#endif DBGPRINT(RT_DEBUG_TRACE, "<-- %s: adapter present\n", __FUNCTION__); return pAd;out: free_netdev(netdev);out_nonetdev: kfree(pAd);out_noalloc: usb_put_dev(dev); DBGPRINT(RT_DEBUG_TRACE, "<-- %s: adapter=NULL\n", __FUNCTION__); return NULL;}//Disconnect function is called within exit routinestatic void usb_rtusb_disconnect(struct usb_device *dev, void *ptr){ PRTMP_ADAPTER pAd = (PRTMP_ADAPTER) ptr; DBGPRINT(RT_DEBUG_TRACE,"--> %s\n", __FUNCTION__); if (!pAd) { DBGPRINT(RT_DEBUG_ERROR, "- (%s) NULL adapter ptr!\n", __FUNCTION__); return; } netif_device_detach(pAd->net_dev); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); // for debug, wait to show some messages to /proc system udelay(1); //After Add Thread implementation, Upon exec there, pAd->net_dev seems becomes NULL, //need to check why??? //assert(pAd->net_dev != NULL) // Can call close function - bb if(pAd->net_dev != NULL) { DBGPRINT(RT_DEBUG_INFO, "unregister_netdev\n"); unregister_netdev (pAd->net_dev); } udelay(1); udelay(1); tasklet_kill(&pAd->rx_bh); tasklet_kill(&pAd->rx_bk); KillThreads(pAd); ReleaseAdapter(pAd, TRUE, FALSE); // Free URB and transfer buffer memory. MlmeFreeMemoryHandler(pAd); free_netdev(pAd->net_dev); kfree(pAd); usb_put_dev(dev); DBGPRINT(RT_DEBUG_TRACE,"<-- %s\n", __FUNCTION__); KPRINT(KERN_INFO, "disconnected\n");}#else // Kernel version > 2.5.0#ifdef CONFIG_PMstatic int rt73_suspend(struct usb_interface *intf, pm_message_t state){ DBGPRINT(RT_DEBUG_TRACE,"---> rt73_suspend()\n"); return common_suspend((PRTMP_ADAPTER)usb_get_intfdata(intf));}static int rt73_resume(struct usb_interface *intf){ DBGPRINT(RT_DEBUG_TRACE,"---> rt73_resume()\n"); return common_resume((PRTMP_ADAPTER)usb_get_intfdata(intf));}#endifstatic int usb_rtusb_probe (struct usb_interface *intf, const struct usb_device_id *id){ struct usb_device *dev = interface_to_usbdev(intf); PRTMP_ADAPTER pAd; int i; struct net_device *netdev; int res = -ENOMEM; DBGPRINT(RT_DEBUG_TRACE,"--> %s (2.6)\n", __FUNCTION__); 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) { KPRINT(KERN_INFO, "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) { KPRINT(KERN_CRIT, "Device Descriptor not matching\n"); goto out_noalloc; } /* RTMP_ADAPTER is too big with 64-bit pointers, and using the builtin net_device private area causes the allocation to exceed 128KB and fail. So we allocate it separately. */ pAd = kzalloc(sizeof (*pAd), GFP_KERNEL); if (!pAd) { KPRINT(KERN_CRIT, "couldn't allocate RTMP_ADAPTER\n"); goto out_noalloc; } netdev = alloc_etherdev(0); if (!netdev) { KPRINT(KERN_CRIT, "alloc_etherdev failed\n"); goto out_nonetdev; } netdev->priv = pAd; pAd->net_dev = netdev; netif_stop_queue(netdev); pAd->config = &dev->config->desc; pAd->pUsb_Dev = dev; SET_MODULE_OWNER(netdev); ether_setup(netdev); netdev->open = usb_rtusb_open; netdev->stop = usb_rtusb_close; netdev->hard_start_xmit = RTMPSendPackets; netdev->get_stats = rt73_get_ether_stats;#if WIRELESS_EXT >= 12#if WIRELESS_EXT < 17 netdev->get_wireless_stats = rt73_get_wireless_stats;#endif netdev->wireless_handlers = (struct iw_handler_def *) &rt73_iw_handler_def;#endif netdev->do_ioctl = rt73_ioctl; netdev->hard_header_len = 14; netdev->mtu = 1500; netdev->addr_len = 6; //netdev->weight = 64; // Used only for poll. N/A in 2.6.24 - bb OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); pAd->MLMEThr_pid= -1; pAd->RTUSBCmdThr_pid= -1; SET_NETDEV_DEV(netdev, &intf->dev); {// find available int i=0; char slot_name[IFNAMSIZ]; //struct net_device *device; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; if (ifname == NULL) strcpy(pAd->net_dev->name, "wlan%d"); else strncpy(pAd->net_dev->name, ifname, IFNAMSIZ); for (i = 0; i < 8; i++) { sprintf(slot_name, pAd->net_dev->name, i);#if 1 if(dev_get_by_name(slot_name)==NULL) break;#else read_lock_bh(&dev_base_lock); // avoid multiple init for (device = first_net_device(); device != NULL; device = next_net_device(device)) { if (strncmp(device->name, slot_name, IFNAMSIZ) == 0) { break; } } read_unlock_bh(&dev_base_lock); if(device == NULL) break;#endif } if(i == 8) { DBGPRINT(RT_DEBUG_ERROR, "No available slot name\n"); KPRINT(KERN_CRIT, "No available slot name\n"); goto out; } sprintf(pAd->net_dev->name, slot_name, i); DBGPRINT(RT_DEBUG_INFO, "usb device name %s\n", pAd->net_dev->name); /* get the active interface descriptor */ iface_desc = intf->cur_altsetting; /* check out the endpoint: it has to be Interrupt & IN */ endpoint = &iface_desc->endpoint[i].desc; /* get Max Packet Size from endpoint */ pAd->BulkOutMaxPacketSize = le16_to_cpu(endpoint->wMaxPacketSize); // Workaround for EDIMAX 7318USg suggested by Ivo in forum if (pAd->BulkOutMaxPacketSize == 0) { pAd->BulkOutMaxPacketSize = 1; DBGPRINT(RT_DEBUG_WARN, "- %s: Device reports zero length wMaxPacketSize. " "Using workaround.\n", __FUNCTION__); KPRINT(KERN_WARNING, "Device reports zero length wMaxPacketSize. " "Using workaround.\n"); } DBGPRINT(RT_DEBUG_INFO, "BulkOutMaxPacketSize %d\n", pAd->BulkOutMaxPacketSize); } res = register_netdev(netdev); if (res) { KPRINT(KERN_CRIT, "register_netdev failed err=%d\n",res); goto out; } usb_set_intfdata(intf, pAd); rt73usb_open_debugfs(pAd); res = common_probe(pAd); if (res) goto out; DBGPRINT(RT_DEBUG_TRACE, "<-- %s: res=%d\n", __FUNCTION__, res); return 0;out: free_netdev(netdev);out_nonetdev: kfree(pAd);out_noalloc: usb_put_dev(dev); DBGPRINT(RT_DEBUG_TRACE, "<-- %s: res=%d\n", __FUNCTION__, res); return res;}static void usb_rtusb_disconnect(struct usb_interface *intf){ struct usb_device *dev = interface_to_usbdev(intf); PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)NULL; DBGPRINT(RT_DEBUG_TRACE,"--> %s\n", __FUNCTION__); pAd = usb_get_intfdata(intf); if (!pAd) { DBGPRINT(RT_DEBUG_ERROR, "- (%s) NULL adapter ptr!\n", __FUNCTION__); return; } netif_device_detach(pAd->net_dev); usb_set_intfdata(intf, NULL); RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); DBGPRINT(RT_DEBUG_INFO,"disconnect usbnet usb-%s-%s\n", dev->bus->bus_name, dev->devpath); rt73usb_close_debugfs(pAd); // for debug, wait to show some messages to /proc system udelay(1); //After Add Thread implementation, Upon exec there, pAd->net_dev seems becomes NULL, //need to check why??? //assert(pAd->net_dev != NULL) // Can call close function - bb if(pAd->net_dev!= NULL) { DBGPRINT(RT_DEBUG_INFO, "unregister_netdev\n"); unregister_netdev (pAd->net_dev); } udelay(1); tasklet_kill(&pAd->rx_bh); tasklet_kill(&pAd->rx_bk); KillThreads(pAd); // Free the entire adapter object ReleaseAdapter(pAd, TRUE, FALSE); MlmeFreeMemoryHandler(pAd); //Free MLME memory handler free_netdev(pAd->net_dev); kfree(pAd); usb_put_dev(dev); DBGPRINT(RT_DEBUG_TRACE,"<-- %s\n", __FUNCTION__); KPRINT(KERN_INFO, "disconnected\n");}#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) *///// Driver module load function//INT __init usb_rtusb_init(void){ KPRINT(KERN_INFO, "init\n"); #ifdef DBG RTDebugLevel = debug; #else if (debug) {} // keep compiler from complaining #endif if ( strlen(firmName) > FIRMWARE_NAME_MAX ) { DBGPRINT(RT_DEBUG_ERROR,"Firmware name too long\n"); return -E2BIG; } return usb_register(&rtusb_driver);}//// Driver module unload function//VOID __exit usb_rtusb_exit(void){ udelay(1); udelay(1); usb_deregister(&rtusb_driver); KPRINT(KERN_INFO, "exit\n");}/**************************************/module_init(usb_rtusb_init);module_exit(usb_rtusb_exit);/**************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -