1. 程式人生 > >usb網絡卡註冊流程

usb網絡卡註冊流程

通訊管理機所用usb網絡卡、AX88772B、 smsc95xx

D:\z_linux_picohood_project\board-support\linux-4.4.x-mainline\drivers\net\usb\asix_devices.c

static const struct driver_info ax88772b_info = {
	.description = "ASIX AX88772B USB 2.0 Ethernet",
	.bind = ax88772_bind,
	.unbind = ax88772_unbind,
	.status = asix_status,
	.link_reset = ax88772_link_reset,
	.reset = ax88772_reset,
	.flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR |
	         FLAG_MULTI_PACKET,
	.rx_fixup = asix_rx_fixup_common,
	.tx_fixup = asix_tx_fixup,
	.data = FLAG_EEPROM_MAC,
};
static const struct usb_device_id	products [] = {
{
	// ASIX AX88772B 10/100
	USB_DEVICE (0x0b95, 0x772b),
	.driver_info = (unsigned long) &ax88772b_info,
},  

一、網絡卡驅動asix註冊

static struct usb_driver asix_driver = {
	.name =		DRIVER_NAME,
	.id_table =	products,
	.probe =	usbnet_probe,
	.suspend =	usbnet_suspend,
	.resume =	usbnet_resume,
	.disconnect =	usbnet_disconnect,
	.supports_autosuspend = 1,
	.disable_hub_initiated_lpm = 1,
};

module_usb_driver(asix_driver);

二、分析 module_usb_driver(asix_driver)

#define module_usb_driver(__usb_driver)         module_driver(__usb_driver, usb_register,  usb_deregister)
#define usb_register(driver)     usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME)    

module_usb_driver函式,回撥usb_register,usb_register最終會呼叫 usb_register_driver 函式來進行usb驅動註冊

三、分析 module_usb_driver(asix_driver)

int usb_register_driver(struct usb_driver *new_driver, struct module *owner,
			const char *mod_name)
{
	int retval = 0;

	if (usb_disabled())
		return -ENODEV;

	new_driver->drvwrap.for_devices = 0;
	new_driver->drvwrap.driver.name = new_driver->name;
	new_driver->drvwrap.driver.bus = &usb_bus_type;
	new_driver->drvwrap.driver.probe = usb_probe_interface;
	new_driver->drvwrap.driver.remove = usb_unbind_interface;
	new_driver->drvwrap.driver.owner = owner;
	new_driver->drvwrap.driver.mod_name = mod_name;
	spin_lock_init(&new_driver->dynids.lock);
	INIT_LIST_HEAD(&new_driver->dynids.list);

	retval = driver_register(&new_driver->drvwrap.driver);
        ..........
        ..........
}
usb_register_driver是一個驅動框架函式,driver_register函式最終會呼叫&usb_bus_type匯流排裡的匹配函式
struct bus_type usb_bus_type = {
	.name =		"usb",
	.match =	usb_device_match,
	.uevent =	usb_uevent,
};
static int usb_device_match(struct device *dev, struct device_driver *drv)
{
	/* devices and interfaces are handled separately */
	if (is_usb_device(dev)) {

		/* interface drivers never match devices */
		if (!is_usb_device_driver(drv))
			return 0;

		/* TODO: Add real matching code */
		return 1;

	} else if (is_usb_interface(dev)) {
		struct usb_interface *intf;
		struct usb_driver *usb_drv;
		const struct usb_device_id *id;

		/* device drivers never match interfaces */
		if (is_usb_device_driver(drv))
			return 0;

		intf = to_usb_interface(dev);
		usb_drv = to_usb_driver(drv);

		id = usb_match_id(intf, usb_drv->id_table);
		if (id)
			return 1;

		id = usb_match_dynamic_id(intf, usb_drv);
		if (id)
			return 1;
	}

	return 0;
}

 如果 usb_device_match匹配成功,則會呼叫最頂層的

asix_driver的probe函式
int usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
	struct usbnet			*dev;
	struct net_device		*net;
	struct usb_host_interface	*interface;
	struct driver_info		*info;
	struct usb_device		*xdev;
	int				status;
	const char			*name;
	
	struct usbnet			*dev11;
	struct usb_driver 	*driver = to_usb_driver(udev->dev.driver);
        。。。。
        。。。。
	xdev = interface_to_usbdev (udev);
	interface = udev->cur_altsetting;

	status = -ENOMEM;

	// set up our own records
	net = alloc_etherdev(sizeof(*dev));
        //////////////////////////////////////////////
        插入自己修改網絡卡比編號的程式碼
        //////////////////////////////////////////////
	status = register_netdev (net);
	netif_info(dev, probe, dev->net,
		   "register '%s' at usb-%s-%s, %s, %pM\n",
		   udev->dev.driver->name,
		   xdev->bus->bus_name, xdev->devpath,
		   dev->driver_info->description,
		   net->dev_addr);
。。。。。。。。。。。 

  

四、修改網絡卡編號的程式碼

		if(!strcmp("musb-hdrc.0.auto",xdev->bus->bus_name))
			{
				if(!strcmp ("1.5",xdev->devpath))
				{
					/*eth0 */
					//dev_change_name(net,"eth50");
					//strcpy (net->name, "eth0");
					strcpy (net->name, "eth1");
				
				}
				if(!strcmp ("1.1",xdev->devpath))
				{
					/*eth2 */
					//dev_change_name(net,"eth52");
					//strcpy (net->name, "eth2");
					strcpy (net->name, "eth0");
					
				}		
			}
			else if(!strcmp ("musb-hdrc.1.auto",xdev->bus->bus_name))
			{
				if(!strcmp ("1.5",xdev->devpath))
				{
					/*eth1 */
					//dev_change_name(net,"eth51");
					//strcpy (net->name, "eth1");
					strcpy (net->name, "eth3");
				}
				if(!strcmp ("1.1",xdev->devpath))
				{
					/*eth3 */
					//dev_change_name(net,"eth53");
					//strcpy (net->name, "eth3");
					strcpy (net->name, "eth2");
		
				}
			
			}

  

  

  

 

usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)