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

📄 rtusb_main.c

📁 台湾RALink公司的 rt2570无线 802.11g 网卡的 驱动的源代码 ,支持linux2.4以上的 内河
💻 C
📖 第 1 页 / 共 4 页
字号:

	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);
	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->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, 4) == 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);

	return pAdapter;
out3:
	printk("3 register_netdev failed err=%d\n",res);

	return NULL;
}
//Disconnect function is called within exit routine
static 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);
	}
	udelay(1);
	udelay(1);

	while (MOD_IN_USE > 0) {
		MOD_DEC_USE_COUNT;
	}
	udelay(1);
	DBGPRINT(RT_DEBUG_ERROR,"<=== RTUSB disconnect successfully\n");

}

#else
static 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 (pAdapter->MLMEThr_pid >= 0) 
	{
		mlme_kill = 1;
		RTUSBUp(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;
		RTUSBUp(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);
	}
	RTUSBHalt( pAdapter, FALSE);
	DBGPRINT(RT_DEBUG_TEMP,"<--usb_rt2570_close\n");

	return 0;
}

int MlmeThread(void * Context)
{
	PRT2570ADAPTER	pAdapter = (PRT2570ADAPTER)Context;

	daemonize("rt2500usb");
	allow_signal(SIGTERM);
	current->flags |= PF_NOFREEZE;
	/* signal that we've started the thread */
	complete(&(pAdapter->notify));
#if 1
	while (1)
	{
		//if(down_interruptible(&pAdapter->mlme_semaphore))
			//break;

		/* lock the device pointers */
		down(&(pAdapter->mlme_semaphore));

		if (mlme_kill)
			break;

		/* lock the device pointers , need to check if required*/
		down(&(pAdapter->usbdev_semaphore));
#if 0
		if (current->flags & PF_FREEZE) {
			refrigerator(0);
		}
#endif
		MlmeHandler(pAdapter);		

		/* unlock the device pointers */
		up(&(pAdapter->usbdev_semaphore));
	}
#else
	// I tried this way for thread handling
	while(1)
	{
		timeout = next_tick;
		do {
			timeout = interruptible_sleep_on_timeout (&pAdapter->MLMEThr_wait, timeout);
			/* make swsusp happy with our thread */
			if (current->flags & PF_FREEZE)
				refrigerator(PF_FREEZE);
			DBGPRINT(RT_DEBUG_TRACE, "current->flags  = 0x%x\n",current->flags );
		} while (!signal_pending (current) && (timeout > 0));

		if (signal_pending (current)) {
			flush_signals(current);
		}

		if (mlme_kill)
			break;
	}
#endif

	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
	complete_and_exit (&pAdapter->notify, 0);
	DBGPRINT(RT_DEBUG_TRACE, "<---MlmeThread\n");

}
int RTUSBCmdThread(void * Context)
{

	PRT2570ADAPTER	pAdapter = (PRT2570ADAPTER)Context;

	daemonize("rt2500usb");
	allow_signal(SIGTERM);
	current->flags |= PF_NOFREEZE;
	/* signal that we've started the thread */
	complete(&(pAdapter->notify));

	while (1)
	{
		//if(down_interruptible(&pAdapter->mlme_semaphore))
			//break;

		/* lock the device pointers */
		down(&(pAdapter->RTUSBCmd_semaphore));

		if (RTUSBCmd_kill)
			break;

		/* lock the device pointers , need to check if required*/
		down(&(pAdapter->usbdev_semaphore));
#if 0
		if (current->flags & PF_FREEZE) {
			refrigerator(0);
		//	continue;
		}
#endif
		CMDHandler(pAdapter);		

		/* unlock the device pointers */
		up(&(pAdapter->usbdev_semaphore));
	}

	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
	complete_and_exit (&pAdapter->notify, 0);
	DBGPRINT(RT_DEBUG_TRACE, "<---RTUSBCmdThread\n");

}
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 (dev->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
			dev->descriptor.idProduct == rtusb_usb_id[i].idProduct)
		{
			printk("idVendor = 0x%x, idProduct = 0x%x \n",dev->descriptor.idVendor, 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);
	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
	netdev->get_wireless_stats = RTUSB_get_wireless_stats;
	netdev->wireless_handlers = (struct iw_handler_def *) &rt2500usb_iw_handler_def;
#endif
	netdev->do_ioctl = usb_rt2570_ioctl;
#endif
	pAdapter->net->hard_header_len = 14;
	pAdapter->net->mtu = 1500;
	pAdapter->net->addr_len = 6;
	pAdapter->net->weight = 64;
	pAdapter->MediaState = NdisMediaStateDisconnected;
	pAdapter->MLMEThr_pid= -1;
	pAdapter->RTUSBCmdThr_pid= -1;
	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, 4) == 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);


	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 rtusb WLAN Card");
MODULE_AUTHOR("Ralink Drivers Group");
MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
MODULE_LICENSE("GPL");

module_init(usb_rtusb_init);	// initialization function
module_exit(usb_rtusb_exit);	// exit function
/**************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -