在这章所说的设备注册和初始化是指WPAN网络设备的注册和初始化,而不是SPI总线设备的设备注册。下面这张图表示CC2420 probe函数中如何注册WPAN的过程。
下面详细讲解每个函数的作用:
1. IEEE 802.15.4_alloc_device
1: struct ieee802154_dev *ieee802154_alloc_device(size_t priv_size,
2: struct ieee802154_ops *ops)
3: {
4: struct wpan_phy *phy;
5: struct ieee802154_priv *priv;
6:
7: phy = wpan_phy_alloc(ALIGN(sizeof(*priv), NETDEV_ALIGN) + priv_size); // 给wpan_phy结构分配空间
8: if (!phy) {
9: printk(KERN_ERR "Failure to initialize master IEEE802154 devicen");
10: return NULL;
11: }
12:
13: priv = wpan_phy_priv(phy);
14: priv->hw.phy = priv->phy = phy; // private数据和ieee802154_dev数据中wpan_phy初始化为相同的phy
15:
16: priv->hw.priv = (char *)priv + ALIGN(sizeof(*priv), NETDEV_ALIGN);
17:
18: BUG_ON(!ops);
19: BUG_ON(!ops->xmit);
20: BUG_ON(!ops->ed);
21: BUG_ON(!ops->start);
22: BUG_ON(!ops->stop);
23:
24: priv->ops = ops; // 芯片驱动所对应的操作
25:
26: INIT_LIST_HEAD(&priv->slaves);
27: mutex_init(&priv->slaves_mtx);
28:
29: return &priv->hw;
30: }
31: EXPORT_SYMBOL(ieee802154_alloc_device);
2. IEEE 802.15.4_register_device
1: int ieee802154_register_device(struct ieee802154_dev *dev)
2: {
3: struct ieee802154_priv *priv = ieee802154_to_priv(dev);
4: int rc;
5:
6: priv->dev_workqueue =
7: create_singlethread_workqueue(wpan_phy_name(priv->phy));
8: if (!priv->dev_workqueue) {
9: rc = -ENOMEM;
10: goto out;
11: }
12:
13: wpan_phy_set_dev(priv->phy, priv->hw.parent);
14:
15: priv->phy->add_iface = ieee802154_add_iface; /* net_device在这个函数里初始化 */
16: priv->phy->del_iface = ieee802154_del_iface;
17:
18: rc = wpan_phy_register(priv->phy); /* 注册WPAN物理层设备,实际上就是注册一个设备
19: device_add(&phy->dev);*/
20: if (rc < 0)
21: goto out_wq;
22:
23: return 0;
24:
25: out_wq:
26: destroy_workqueue(priv->dev_workqueue);
27: out:
28: return rc;
29: }
30: EXPORT_SYMBOL(ieee802154_register_device);
3. ieee802154_add_iface
1: struct net_device *ieee802154_add_iface(struct wpan_phy *phy, const char *name, int type)
2: {
3: struct net_device *dev;
4: int err = -ENOMEM;
5:
6: /* 根据设备工作模式来初始化net_dev结构 */
7: switch (type) {
8: case IEEE802154_DEV_WPAN:
9: dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
10: name, ieee802154_wpan_setup);
11: break;
12: case IEEE802154_DEV_MONITOR:
13: dev = alloc_netdev(sizeof(struct ieee802154_sub_if_data),
14: name, ieee802154_monitor_setup);
15: break;
16: default:
17: dev = NULL;
18: err = -EINVAL;
19: break;
20: }
21: if (!dev)
22: goto err;
23:
24: err = ieee802154_netdev_register(phy, dev); /* 注册IEEE 802.15.4 网络设备 */
25:
26: if (err)
27: goto err_free;
28:
29: dev_hold(dev); /* we return a device w/ incremented refcount */
30: return dev;
31:
32: err_free:
33: free_netdev(dev);
34: err:
35: return ERR_PTR(err);
36: }