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

📄 zdusb.c

📁 Atheros USB WiFi Card 驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    return 0;
}
#endif

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
static void *zd1211_probe(struct usb_device *dev, unsigned int ifnum,
			   const struct usb_device_id *id)
#else
static int zd1211_probe(struct usb_interface *interface,
	const struct usb_device_id *id)
#endif			   
{
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
	struct usb_interface *interface = &dev->actconfig->interface[ifnum];
#else
	struct usb_device *dev = interface_to_usbdev(interface);
#endif
	
	struct net_device *net = NULL;
	struct zd1205_private *macp = NULL;
	int vendor_id, product_id;
	int dev_index = id - zd1211_ids;
	int result = 0;
    
	//char serial_number[30];
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
 //Drivers for USB interfaces should normally record such references in
 //their probe() methods, when they bind to an interface, and release
 //them by calling usb_put_dev(), in their disconnect() methods.
 //A pointer to the device with the incremented reference counter is returned.
	usb_get_dev(dev);
#endif    

	vendor_id = zd_le16_to_cpu(dev->descriptor.idVendor);
	product_id = zd_le16_to_cpu(dev->descriptor.idProduct);

#if 1
	printk(KERN_NOTICE "vendor_id = %04x\n", vendor_id);
	printk(KERN_NOTICE "product_id = %04x\n", product_id);

	if (dev->speed == USB_SPEED_HIGH)
		printk(KERN_NOTICE "USB 2.0 Host\n");
	else
		printk(KERN_NOTICE "USB 1.1 Host\n");  
#endif
	
	//memset(serial_number, 0, 30);
	//usb_string(dev, dev->descriptor.iSerialNumber, serial_number, 29);
	//printk("Device serial number is %s\n", serial_number);

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))	
	if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
        	printk(KERN_ERR "usb_set_configuration() failed\n");
		result = -EIO;
		goto fail;
	}
#endif
    
#if 1
	//kernel 2.6
	if (!(macp = kmalloc(sizeof(struct zd1205_private), GFP_KERNEL))) {
		printk(KERN_ERR "out of memory allocating device structure\n");
		result = -ENOMEM;
		goto fail;
	}
	
	memset(macp, 0, sizeof(struct zd1205_private));
#endif		
    macp->UpTime = jiffies;


#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
	usb_inc_dev_use(dev);
#endif    

	net = alloc_etherdev(0);  //kernel 2.6
	//net = alloc_etherdev(sizeof (struct zd1205_private));  //kernel 2.4

	if (!net) {
		printk(KERN_ERR "zd1211: Not able to alloc etherdev struct\n");
		result = -ENOMEM;
		goto fail1;
	}
	
	g_dev = net;  //save this for CBs use
	//macp = net->priv; //kernel 2.4
	net->priv = macp;   //kernel 2.6
	macp->device = net;
	macp->usb = dev;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24))   
	SET_MODULE_OWNER(net);
#endif
	macp->dev_index = dev_index;
	macp->release = zd_le16_to_cpu(dev->descriptor.bcdDevice);
	printk(KERN_NOTICE "Release Ver = %04x\n", macp->release);
	macp->flags = 0;
	macp->dbg_flag = ZD1211_DBG_LEVEL;

	/* set up the endpoint information */
	/* check out the endpoints */
	macp->interface = interface;
	
	init_waitqueue_head(&macp->regSet_wait);
	init_waitqueue_head(&macp->iorwRsp_wait);
	init_waitqueue_head(&macp->term_wait);
	init_waitqueue_head(&macp->msdelay);

	if (!zd1211_alloc_all_urbs(macp)){
        printk("Calling zd1211_alloc_all_urbs fails\n");
		result = -ENOMEM;
		goto fail2;
	}	

	//zd1211_DownLoadUSBCode(macp, "WS11Uext.bin", NULL, cFIRMWARE_EXT_CODE);
    //If the driver was removed and reinstall without unplug the device.
    //You can tell the driver not to download the firmware again by issing
    //insmod zd1211b zd1211_FirstDown=0. Redownload causes device crash
    if(zd1211_FirstLoad) 
    {
        if (zd1211_Download_IncludeFile(macp) != 0){
            printk(KERN_ERR "zd1211_Download_IncludeFile failed\n");
            result = -EIO;
            goto fail3;
        }
    }

	//to enable firmware
//#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))    
//	if (usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
//#else
//	if (usb_set_interface(dev, interface->altsetting[0].desc.bInterfaceNumber, 	0)){
        // Use the lowest USBD API to issue set_configuration command.
    if ((usb_control_msg(dev, usb_sndctrlpipe(dev,0),USB_REQ_SET_CONFIGURATION,0, 1, 0, NULL, 0, HZ))<0)
    {
//#endif        
		printk(KERN_ERR "usb_set_configuration() failed\n");
		result = -EIO;
		goto fail3;
	}
	
	set_bit(ZD1211_RUNNING, &macp->flags);
	macp->bUSBDeveiceAttached = 1;

 	if (!zd1211_InitSetup(net, macp))
    {
        printk("Calling zd1211_InitSetup fails\n");
		result = -EIO;
		goto fail3;
	}
	else
    {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
		usb_set_intfdata(interface, macp);
		SET_NETDEV_DEV(net, &interface->dev);
		//defer_kevent(macp, KEVENT_REGISTER_NET);
#endif

#if 1 //don't register net
		if (register_netdev(net) != 0) 
        {
            printk("register_netdev fails\n");
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))            
			usb_set_intfdata(interface, NULL);
#endif            
			goto fail3;
		}
#endif          
	}
    
	goto done;    
	
 fail3:
	zd1211_free_all_urbs(macp);	

 fail2:
	free_netdev(net);  //kernel 2.6
	//kfree(net);
    
 fail1:
	kfree(macp);
    
 fail:
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
	usb_put_dev(dev);
#endif
	macp = NULL;
        goto exit;
done: 
    netif_carrier_off(macp->device); 
exit:
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
	return macp;
#else
	return result;
#endif	
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
static void zd1211_disconnect(struct usb_device *dev, void *ptr)
#else
static void zd1211_disconnect(struct usb_interface *interface)
#endif
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
	struct zd1205_private *macp = (struct zd1205_private *) usb_get_intfdata(interface);
#else
	struct zd1205_private *macp = (struct zd1205_private *)ptr;
#endif	

	if (!macp) {
		printk(KERN_ERR "unregistering non-existant device\n");
		return;
	}

	set_bit(ZD1211_UNPLUG, &macp->flags);
	macp->bUSBDeveiceAttached = 0;

	if (macp->driver_isolated){
		if (macp->device->flags & IFF_UP)
			zd1205_close(macp->device);
	}
    
	unregister_netdev(macp->device);
    
	//assuming we used keventd, it must quiesce too
	flush_scheduled_work();
    mdelay(1000);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))    
	usb_dec_dev_use(dev);
#else
	usb_put_dev(interface_to_usbdev(interface));
#endif

	zd1211_unlink_all_urbs(macp);
	zd1211_free_all_urbs(macp);
	zd1205_clear_structs(macp->device);
	kfree(macp);
	macp = NULL;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
    if(interface_to_usbdev(interface)->state != USB_STATE_NOTATTACHED)
        usb_reset_device(interface_to_usbdev(interface));
	usb_set_intfdata(interface, NULL);
#endif
	//ZEXIT(0);
}

static struct usb_driver zd1211_driver = {
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))    
	//.owner =		THIS_MODULE,
#endif    
	.name =		    driver_name,
	.probe =		zd1211_probe,
	.disconnect =	zd1211_disconnect,
	.id_table =	    zd1211_ids,
#if ZDCONF_ACPI_SUPPORT == 1
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
    .suspend  =     zd1211_suspend,
    .resume   =     zd1211_resume,
#endif
#endif

};


int __init zd1211_init(void)
{
        printk("\n");
        printk(" _____     ____    _    ____\n");
        printk("|__  /   _|  _ \\  / \\  / ___|\n");
        printk("  / / | | | | | |/ _ \\ \\___ \\\n");
        printk(" / /| |_| | |_| / ___ \\ ___) |\n");
        printk("/____\\__, |____/_/   \\_\\____/\n");
        printk("     |___/\n");

	printk(KERN_NOTICE "%s - version %s\n",  DRIVER_NAME, VERSIONID);
	return usb_register(&zd1211_driver);
}

void __exit zd1211_exit(void)
{
	usb_deregister(&zd1211_driver);
}

module_init(zd1211_init);
module_exit(zd1211_exit);

⌨️ 快捷键说明

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