usb網絡卡註冊流程
阿新 • • 發佈:2018-11-13
通訊管理機所用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)