⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtmp_main.c

📁 r73模块的无线网卡在Linux下的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -