7.19 Linux内核的面向对象思想:多态
多态
编译时多态:重载
Kmalloc函数
运行时多态:覆盖
回调函数
代码
rtl8150_probe 负责初始化驱动
内嵌了8150的结构体指针
封装了一个netdev_ops的接口
static int rtl8150_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
//申请一个usb device
rtl8150_t *dev; //内嵌了8150的结构体指针
struct net_device *netdev;
netdev = alloc_etherdev(sizeof(rtl8150_t));
//申请一个网卡设备
if (!netdev)
return -ENOMEM;
dev = netdev_priv(netdev);
dev->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL);
if (!dev->intr_buff) {
free_netdev(netdev);
return -ENOMEM;
}
tasklet_init(&dev->tl, rx_fixup, (unsigned long)dev);
spin_lock_init(&dev->rx_pool_lock);
dev->udev = udev; //usb device 加载到8150 device
dev->netdev = netdev; //net device 加载到8150 device
netdev->netdev_ops = &rtl8150_netdev_ops;
//封装了一个netdev_ops的接口
netdev->watchdog_timeo = RTL8150_TX_TIMEOUT;
netdev->ethtool_ops = &ops;
dev->intr_interval = 100; /* 100ms */
if (!alloc_all_urbs(dev)) {
dev_err(&intf->dev, "out of memory\n");
goto out;
}
if (!rtl8150_reset(dev)) {
dev_err(&intf->dev, "couldn't reset the device\n");
goto out1;
}
fill_skb_pool(dev);
set_ethernet_addr(dev);
usb_set_intfdata(intf, dev);
SET_NETDEV_DEV(netdev, &intf->dev);
if (register_netdev(netdev) != 0) {//注册net device 到linux内核
dev_err(&intf->dev, "couldn't register the device\n");
goto out2;
}
dev_info(&intf->dev, "%s: rtl8150 is detected\n", netdev->name);
return 0;
out2:
usb_set_intfdata(intf, NULL);
free_skb_pool(dev);
out1:
free_all_urbs(dev);
out:
kfree(dev->intr_buff);
free_netdev(netdev);
return -EIO;
}
rtl8150_netdev_ops
static const struct net_device_ops rtl8150_netdev_ops = {
.ndo_open = rtl8150_open,
.ndo_stop = rtl8150_close,
.ndo_do_ioctl = rtl8150_ioctl,
.ndo_start_xmit = rtl8150_start_xmit,
.ndo_tx_timeout = rtl8150_tx_timeout,
.ndo_set_rx_mode = rtl8150_set_multicast,
.ndo_set_mac_address = rtl8150_set_mac_address,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
};