当前位置: 技术问答>linux和unix
在读取硬件寄存器时completion如何工作的?
来源: 互联网 发布时间:2016-11-12
本文导语: 下面的代码是Linux2.6.36网卡fec驱动读取硬件寄存器, completion如何工作的,如何知道寄存器读取完毕?completion如何超时? static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { struct fec_enet_private *fep = bus->...
下面的代码是Linux2.6.36网卡fec驱动读取硬件寄存器,
completion如何工作的,如何知道寄存器读取完毕?completion如何超时?
static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
struct fec_enet_private *fep = bus->priv;
unsigned long time_left;
fep->mii_timeout = 0;
init_completion(&fep->mdio_done);
/* start a read op */
writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) |
FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
time_left = wait_for_completion_timeout(&fep->mdio_done,
usecs_to_jiffies(FEC_MII_TIMEOUT));
if (time_left == 0) {
fep->mii_timeout = 1;
printk(KERN_ERR "wsy::fec_enet_mdio_read: MDIO read timeoutn");
return -ETIMEDOUT;
}
returnFEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
}
completion如何工作的,如何知道寄存器读取完毕?completion如何超时?
static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
struct fec_enet_private *fep = bus->priv;
unsigned long time_left;
fep->mii_timeout = 0;
init_completion(&fep->mdio_done);
/* start a read op */
writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
FEC_MMFR_PA(mii_id) | FEC_MMFR_RA(regnum) |
FEC_MMFR_TA, fep->hwp + FEC_MII_DATA);
/* wait for end of transfer */
time_left = wait_for_completion_timeout(&fep->mdio_done,
usecs_to_jiffies(FEC_MII_TIMEOUT));
if (time_left == 0) {
fep->mii_timeout = 1;
printk(KERN_ERR "wsy::fec_enet_mdio_read: MDIO read timeoutn");
return -ETIMEDOUT;
}
returnFEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
}
|
completion是一种同步的机制。
使用的API为
init_completion()
wait_for_completion_timeout() -- 等待某个事件发生,未发生该进程休眠
complete() -- 告知事件已发生,唤醒等待该事件的进程。通常你会看到在中断处理程序里调用它。(也有可能通过轮询,也就是读状态寄存器来判断了)
使用的API为
init_completion()
wait_for_completion_timeout() -- 等待某个事件发生,未发生该进程休眠
complete() -- 告知事件已发生,唤醒等待该事件的进程。通常你会看到在中断处理程序里调用它。(也有可能通过轮询,也就是读状态寄存器来判断了)
|
在你的中断处理函数里,有具体的实现代码,比如要读取100个字节,当读到硬件发来的第100个字节后,就调用completion()通知等待队列上等待这个事件的进程,completion()的具体实现就是wake_up(),跟代码就可以看到。