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)
浙公网安备 33010602011771号