二、下面说一下 mini2440_dm9k_resource 中的几个地址是怎么计算得来的。地址的计算在驱动移植中也是一个重要的部分。地址的计算在网上的博客中很少有介绍的,自己看了很久才琢磨明白。
DM9000 MINI2440 功能描述
SD0 DATA0 数据信号
| |
SD15 DATA15 数据信号
CMD ADDR2 识别为地址还是数据
INT EINT7 中断
IOR# nOE 读命令使能
IOW# nWE 写命令使能
AEN nGCS4 片选使能
1. dm9000的使能管教AEN与nGCS4相连,nGCS4从2440的数据手册中可以看到,它对应的地址就是从0x20000000开始的。 0x300 是从dm9000的数据手册中得来的,手册中讲到dm9000的IO有8个起始地址偏移0x300、0x310、0x320...0x370,不知为何这里用的是0x300.
2. 上面的resource array中,第0项是代表io_addr,addr2为0的话,正好对应到addr2addr1addr0 是 3-0这个范围,也就是第0项.end 是 +3 的原因。同理,可以得到为什么io_data是4 ~7
3. 读写dm9000的寄存器时,都是分两步进行操作。先写地址,即向io_addr写入希望操作的dm9000的寄存器的地址,然后下一步在进行读取或者写入的操作。第一步是在io_addr操作,第二步是在io_data操作。这两个连续的步骤,乍一看好像是明白的,但是仔细想又想不明白这样操作的理由
三、 接下来看dm9000_open(struct net_device *dev) 函数。
/*
* Open the interface.
* The interface is opened whenever "ifconfig" actives it.
*/
static int
dm9000_open(struct net_device *dev)
{
board_info_t *db = netdev_priv(dev);
unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
if (netif_msg_ifup(db))
dev_dbg(db->dev, "enabling %s\n", dev->name);
/* If there is no IRQ type specified, default to something that
* may work, and tell the user that this is a problem */
if (irqflags == IRQF_TRIGGER_NONE)
dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
irqflags |= IRQF_SHARED;
if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
return -EAGAIN;
/* Initialize DM9000 board */
dm9000_reset(db);
dm9000_init_dm9000(dev);
/* Init driver variable */
db->dbug_cnt = 0;
mii_check_media(&db->mii, netif_msg_link(db), 1);
netif_start_queue(dev);
dm9000_schedule_poll(db);
return 0;
}
在这个函数中,申请中断资源,dm9000只有一个中断号,产生两种中断:收到包、发送完毕。netif_start_queue表示允许上层进行发包,dm9000_schedule_poll表示 开始周期性额调用dm9000_poll_work.前面在probe函数中, 只是初始化了phy_poll函数,在open函数中,才开始调用,这也才更符合情理。这里我们看到了mii_check_media函数,如果我们将这里的这个函数注销掉,会发生什么情况?经检测,这里将mii_check_media注销后,对驱动并没有明显的影响。在m9000_poll_work函数中注销了mii_check_media,驱动也不受影响。
问题:1. struct device, net_device 分别的应用场合是什么,好像net_device是与sysfs打交道更多。 ?
2. 每次insmod 驱动时,都会显示下面的log,为什么会多次调用dm9000_hash_table这个函数呢?是网络的哪部分函数调用的?
3. dm9000 dm9000: entering dm9000_init_dm9000 dm9000 dm9000: entering dm9000_hash_table dm9000 dm9000: entering dm9000_hash_table 加载模块时,会显示多次进入dm9000_hahs_table这个函数,这是在哪里调用的?