看懂了吗 ? 嗯,我想你懂了。不过我还是解释一下。前面四个分别是
- vendor id : PCI_VENDOR_ID_SI
- device id : PCI_DEVICE_ID_SI_900
- sub vendor id : PCI_ANY_ID
- sub device id : PCI_ANY_ID
初始化
好了,那其它的部份呢 ? 还记意
sis900_pci_driver 中其它的二个项目 probe 和remove 吗 ?
它们是用来初始化和移除一个驱动程序的呼叫。你可以把它们想成驱动程序对象的 constructor 和 destructor 。在 probe
中,你应该由硬件中把一些将来可能会用到的资讯准备好。由于这是一个 PCI
驱动程序,你不必特意去检查装置是否真的存在。但如果你的驱动程序只支持某些特定的硬件,或是你想要检查系统中是否有一些特别的硬件存在,你可以在这里做。例如在这个驱动程序中,对不同版本的硬件,我们用不同的方法去读它的
MAC 地址。
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
if (revision == SIS630E_900_REV || revision == SIS630EA1_900_REV)
ret = sis630e_get_mac_addr(pci_dev, net_dev);
else if (revision == SIS630S_900_REV)
ret = sis630e_get_mac_addr(pci_dev, net_dev);
else
ret = sis900_get_mac_addr(pci_dev, net_dev);
对于 SIS630E SIS630EA1 和 SIS630S 这些整合式芯片而言,其 MAC 地址被储存在 APC CMOS RAM 之中。但对其它独立的芯片而言则是存在网络卡的 EEPROM 之上。
为了不要让这篇文章像流水帐一般,我不仔细的说明 probe 的过程。大家自己揣摸一下吧 !
在 probe 中还有一段比较和后文有关的程序码
net_dev->open = &sis900_open;
net_dev->hard_start_xmit = &sis900_start_xmit;
net_dev->stop = &sis900_close;
net_dev->get_stats = &sis900_get_stats;
net_dev->set_config = &sis900_set_config;
net_dev->set_multicast_list = &set_rx_mode;
net_dev->do_ioctl = &mii_ioctl;
net_dev->tx_timeout = sis900_tx_timeout;
net_dev->watchdog_timeo = TX_TIMEOUT;
我想这很清楚,我们透过 net_dev 这个结构告诉 Linux 网络子系统如何来操作这个装置。当你使用 ifconfig 这个 R 令时,系统会使用 sis900_open 打开这个驱动程序,并使用 set_config 来说定装置的参数,如 IP address 。当有资料需要被传送时, sis900_start_xmit 被用来将资料送入装置之中。接下来,我们就一一的检视这些函数。
初始化装置
sis900_open(struct net_device *net_dev);